无形:Foo [T,U]的UnaryTCConstraint

时间:2016-10-02 22:21:52

标签: scala shapeless

我有以下工作:

import shapeless._
import shapeless.UnaryTCConstraint._
import shapeless.test.illTyped

case class Foo[R](result: R, dependencies: Set[Foo[_]] = Set.empty)

//This method only accepts an HList of Foo
def method[L <: HList](list: L)(implicit utcc: UnaryTCConstraint[L, Foo]) = println("checks")

val notFoos = "abc" :: 1 :: 5.5 :: HNil
illTyped { """method(notFoos)""" }

val aFoo = Foo("abc")
val bFoo = Foo(2, Set(aFoo))
val cFoo = Foo(true, Set(bFoo))
val onlyFoos = aFoo :: bFoo :: cFoo :: HNil
method(onlyFoos) // prints checks

经过一些重构后,我得出的结论是,依赖关系应该是Foos的HList。所以我将代码更改为:

type FooWithAnyDependency[R] = Foo[R, _ <: HList]

case class Foo[R, L <: HList](result: R, dependencies: L = HNil)(implicit utcc: UnaryTCConstraint[L, FooWithAnyDependency])

def method2[L <: HList](list: L)(implicit utcc: UnaryTCConstraint[L, FooWithAnyDependency]) = println("checks")

此代码编译,但是当我尝试使用它时:

val aFoo = Foo("abc")

我收到此错误:

Could not find implicit value for parameter utcc: shapeless.UnaryTCConstraint[shapeless.HNil.type,FooWithAnyDependency]
Error occurred in an application involving default arguments.
val aFoo = Foo("abc")
               ^

我认为它失败了,因为它试图找到一个UnaryTCConstraint [HNil .type ,FooWithAnyDependency]。

我知道实现自定义约束可以解决问题(我已经完成了它),但每当我尝试使用其他东西时,我遇到了同样的问题,例如:Comapped.Aux[L, FooWithAnyDependency, M]。< / p>

所以问题是,如何在不必为Foo重新实现大多数事情的情况下克服这个问题。

1 个答案:

答案 0 :(得分:2)

问题是推断的HNil.type单例类型,你是完全正确的。幸运的是,修复非常简单 - 您只需为HNil提供类型注释:

case class Foo[R, L <: HList](
  result: R,
  dependencies: L = HNil: HNil
)(implicit utcc: UnaryTCConstraint[L, FooWithAnyDependency])

通常在使用Shapeless时,你需要为HNil提供类似这样的类型注释,以避免(或多或少无用)单例类型HNil.type,除非你写这样的东西:

val hlist = 1 :: HNil

仅推断类型Int :: HNil而不是Int :: HNil.type,因为HNil有一个::方法可确保您获得正确的类型。