给出像这样或那样的签名:
def foo[A, F[_]](implicit mon: Monoid[F[A]], pr: Pure[F]): F[A]
Run Code Online (Sandbox Code Playgroud)
假设A是Char,有没有办法获得一个String而不是一个List[Char]?
String不采用类型参数,所以我认为这是不可能的.什么是下一个最佳选择?现在,我使用mkString结果,但这感觉不是最佳的.
我认为String是一个零 的monoid ""并附加 + ...
可以说服String伪装成更高级的类型,因此允许形式的功能foo适用.但是,Scala的类型推断目前还不能胜任推断foo类型参数的工作,所以你必须明确地提供它们,
// Assuming the the definitions of Pure and Monoid from Scalaz
type ConstString = {
type ?[X] = String
}
implicit def StringPure = new Pure[ConstString#?] {
def pure[A](a: => A) = a.toString
}
val sm = implicitly[Monoid[String]]
val sp = implicitly[Pure[ConstString#?]]
val f : String = foo[Char, ConstString#?](sm, sp) // OK
Run Code Online (Sandbox Code Playgroud)
请注意,Char类型参数to foo是未使用的,可以是任何东西,但必须是某种东西:在这种情况下,要么Char是自然选择,Nothing要么Any也可以.
请注意,此解决方案依赖于String特殊特征:所有类型的值都可以转换为Strings,因此pure[A](a : => A) : String可以对所有类型实现A.复制这个习惯用于除了String最有可能必须利用某种机制来实现类型特定情况的类型pure(例如某种模式匹配).