被视为Monoid的字符串

huy*_*hjl 5 scala scalaz

给出像这样或那样的签名:

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 ""附加 + ...

Mil*_*bin 7

可以说服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(例如某种模式匹配).

  • 但是`隐式[Pure [ConstString#λ]] .pure('a')`将返回空字符串,所以这并没有多大用处.是吗? (2认同)

mis*_*tor 6

我能想到的是最好的解决办法是从定义一个隐式转换List[Char]String.