Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why shapeless `everywhere` combinator works inside a method but not in a `val`?

Given this code:

import shapeless._
import poly._

object EverywhereValAndDef {

  sealed trait Tree[T]
  case class Leaf[T](t: T) extends Tree[T]
  case class Node[T](left: Tree[T], right: Tree[T]) extends Tree[T]

  val tree: Tree[Int] =
    Node(
      Node(
        Node(
          Leaf(1),
          Node(
            Leaf(2),
            Leaf(3))),
        Leaf(4)),
      Node(
        Leaf(5),
        Leaf(6)))

  object inc extends ->((i: Int) => i + 1)

  def afterIncDef = everywhere(inc)(tree) // works

  val afterIncVal = everywhere(inc)(tree) // fails

  val expected: Tree[Int] =
    Node(
      Node(
        Node(
          Leaf(2),
          Node(
            Leaf(3),
            Leaf(4))),
        Leaf(5)),
      Node(
        Leaf(6),
        Leaf(7)))

  def eqDef = expected == afterIncDef

  def eqVal = expected == afterIncVal

}

in a repl session I get this results:

Welcome to Scala version 2.11.4 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_25).
Type in expressions to have them evaluated.
Type :help for more information.

scala> EverywhereValAndDef.eqDef
res0: Boolean = true

scala> EverywhereValAndDef.eqVal
res1: Boolean = false

scala> EverywhereValAndDef.tree
res2: EverywhereValAndDef.Tree[Int] = Node(Node(Node(Leaf(1),Node(Leaf(2),Leaf(3))),Leaf(4)),Node(Leaf(5),Leaf(6)))

scala> EverywhereValAndDef.afterIncDef
res3: EverywhereValAndDef.Tree[Int] = Node(Node(Node(Leaf(2),Node(Leaf(3),Leaf(4))),Leaf(5)),Node(Leaf(6),Leaf(7)))

scala> EverywhereValAndDef.afterIncVal
res4: EverywhereValAndDef.Tree[Int] = Node(Node(Node(Leaf(1),Node(Leaf(2),Leaf(3))),Leaf(4)),Node(Leaf(5),Leaf(6)))

Why everywhere is not working in the val case?

like image 769
gerferra Avatar asked Nov 27 '25 05:11

gerferra


1 Answers

If you move the definitions of Tree, Leaf and Node out of EverywhereValAndDef to the top level (or to some other object) then the problem goes away.

I don't have a definitive answer, but it would appear to be a subtle initialization order issue colliding with this Scala macros issue.

like image 116
Miles Sabin Avatar answered Nov 28 '25 20:11

Miles Sabin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!