Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala Fundep物化及其隐含的松散类型信息_Scala_Macros_Scala Macros_Shapeless - Fatal编程技术网

Scala Fundep物化及其隐含的松散类型信息

Scala Fundep物化及其隐含的松散类型信息,scala,macros,scala-macros,shapeless,Scala,Macros,Scala Macros,Shapeless,我试图使用fundep物化来增加编译时安全性。宏的返回类型取决于传递到宏中的字符串(即Foo.scala中的隐式字符串) 我的最终目标是DSL,看起来像这样 "Eggs, Bacon".shoppingList.order 通过使用宏中字符串“Eggs,Bacon”生成的HList,使用order等方法具有隐式参数 我看到一些奇怪的行为 显式调用宏意味着我不能内联调用返回对象上的方法 如果我依赖于使用fundep方法的隐式转换,那么类型将被删除,并且我似乎在对类型进行强制转换,而没有显式强制转

我试图使用fundep物化来增加编译时安全性。宏的返回类型取决于传递到宏中的字符串(即Foo.scala中的隐式字符串)

我的最终目标是DSL,看起来像这样

"Eggs, Bacon".shoppingList.order
通过使用宏中字符串“Eggs,Bacon”生成的HList,使用order等方法具有隐式参数

我看到一些奇怪的行为

  • 显式调用宏意味着我不能内联调用返回对象上的方法
  • 如果我依赖于使用fundep方法的隐式转换,那么类型将被删除,并且我似乎在对类型进行强制转换,而没有显式强制转换
  • 显式具体化然后调用方法是可以的
  • scala具有简化的宏,而FooExample.scala具有奇怪的行为

    有什么办法可以这样做吗

    福斯卡拉

    import shapeless._
    import scala.language.experimental.macros
    import scala.language.implicitConversions
    import scala.reflect.macros.whitebox
    
    class Foo[L <:  HList](val list: L) { self =>
      def foo: Foo[L] = self
    }
    
    object Foo {
      implicit def materializeFoo[L <: HList](foo: String): Foo[L] = macro FooMacro.materialize_foo_impl[L]
    }
    
    object FooMacro {
      def materialize_foo_impl[L <:  HList : c.WeakTypeTag](c: whitebox.Context)(foo: c.Expr[String]): c.Tree = {
        import c.universe._
        q"""{ new Foo($foo :: HNil) }"""
      }
    }
    
    导入无形状_
    导入scala.language.experimental.macros
    导入scala.language.implicitConversions
    导入scala.reflect.macros.whitebox
    类别Foo[L
    def foo:foo[L]=自我
    }
    对象Foo{
    
    隐式def materialiefo[L我目前通过使用路径依赖类型来解决这个问题,这与在无形状库中使用Witness和Singleton的方式非常相似,并添加了一个类似于“shown”的方法来将我的列表转换为所需的类型。
    import shapeless._
    import shapeless.test._
    
    import Foo._
    
    final class Bar[L <: HList](foo: Foo[L]) {
      def bar: L = foo.list
    }
    object FooExample {
    
      implicit def foo2Bar[L <: HList](foo: Foo[L]): Bar[L] = new Bar(foo)
    
      def main(args: Array[String]) {
        val expected = "test" :: HNil
        val notExpected = HNil
    
        val f1 = Foo.materializeFoo("test")
        sameTyped(expected)(f1.list)
    
        val f2 = "test".foo
        sameTyped(f2.list)(expected)
        sameTyped(f2.list)(notExpected)
    
        val l1: String :: HNil = f2.list
    
        //This actually compiles but throws a ClassCastException
        //val l2: HNil = f2.list
    
        illTyped("""Foo.materializeFoo("test").list""")
    
        sameTyped(expected)("test".foo.list)
        sameTyped(notExpected)("test".foo.list)
    
        sameTyped(expected)(f1.bar)
        illTyped("""Foo.materializeFoo("test").bar""")
    
        //I actually just want to call "test".foo.bar and have bar have the correct type
      }
    }