2016-06-30 112 views
2

假设我有容器标记奇怪影响

case class TypedString[T](value: String) 

和局部功能特技

abstract class PartFunc[Actual <: HList] { 
    val poly: Poly 

    def apply[L1 <: HList](l: L1)(implicit 
            mapped: Mapped.Aux[Actual, TypedString, L1], 
            mapper: Mapper[poly.type, L1]): L1 = l 
} 

聚对映射器

object f extends (TypedString ~>> String) { 
    def apply[T](s : TypedString[T]) = s.value 
} 

和结果的方法

用法

例子:

func[ 
    Int :: String :: HNil 
](TypedString[Int]("42") :: TypedString[String]("hello") :: HNil) 

这段代码在编译时失败,因为编译器无法找到Mapped隐含参数:

could not find implicit value for parameter mapped: 
    shapeless.ops.hlist.Mapped[shapeless.::[Int,shapeless.::[String,shapeless.HNil]],nottogether.MapperTest.TypedString]{type Out = shapeless.::[nottogether.MapperTest.TypedString[Int],shapeless.::[nottogether.MapperTest.TypedString[String],shapeless.HNil]]} 
     ](TypedString[Int]("42") :: TypedString[String]("hello") :: HNil) 

但是,如果我们从PartFunc.apply(...)签名删除Mapper隐含参数一切工作正常。所以我不知道为什么以及如何Mapper影响Mapped

回答

3

编译器抱怨Mapped而实际问题与Mapper。我不知道为什么,但似乎有一个Mapped单身类型poly.typepoly是一个抽象值或PartFunc构造参数得到一个错误。

一种解决方案是使poly一个P <: Poly并传递单用Actual类型一起,当我们创建PartFunc

import shapeless._ 
import ops.hlist.{Mapped, Mapper} 
import poly.~>> 

abstract class PartFunc[Actual <: HList, P <: Poly] { 
    val poly: P 
    def apply[L1 <: HList](l: L1)(implicit 
    mapped: Mapped.Aux[Actual, TypedString, L1], 
    mapper: Mapper[P, L1] 
): mapper.Out = mapper(l) 
} 

def func[Actual <: HList] = new PartFunc[Actual, f.type] { val poly = f } 

或用普通班:

class PartFunc[Actual <: HList, P <: Poly](poly: P) { 
    def apply[L1 <: HList](l: L1)(implicit 
    mapped: Mapped.Aux[Actual, TypedString, L1], 
    mapper: Mapper[P, L1] 
): mapper.Out = mapper(l) 
} 

def func[Actual <: HList] = new PartFunc[Actual, f.type](f) 

请注意,我们现在必须写mapper(l),因为l map poly仍然会寻找Mapped[poly.type, L1]

我们现在可以调用func

func[ 
    Int :: String :: HNil 
](TypedString[Int]("42") :: TypedString[String]("hello") :: HNil) 
// String :: String :: HNil = 42 :: hello :: HNil 

我相信有人与一些更深入的Scala的类型系统的知识可以为我们提供更清楚的解释,并可能对这个问题的一个更好的解决方案。

+0

我问这个问题在没有回答的无形回音室里。感谢您的支持。 您建议阅读哪些书或文章以更熟悉scala类型? –