在haskell中,我可以对字符串执行以下操作
let f = sequence [id, reverse]
f "test"
我有点茫然如何使用 Cats 以更好的方法解决这个问题。我目前有类似的东西
val f = List(fun1,fun2)
val data = "test"
f map {fun => fun(data)}
是否有可以使用 Cats 完成此任务的 Sequence 或 SequenceU 的实现?
在haskell中,我可以对字符串执行以下操作
let f = sequence [id, reverse]
f "test"
我有点茫然如何使用 Cats 以更好的方法解决这个问题。我目前有类似的东西
val f = List(fun1,fun2)
val data = "test"
f map {fun => fun(data)}
是否有可以使用 Cats 完成此任务的 Sequence 或 SequenceU 的实现?
它或多或少完全相同,只是语法有点不同,您需要一些额外的导入,并且通用版本不那么方便,因为 ScalaString
不仅仅是字符列表的别名:
import cats.instances.function._, cats.instances.list._, cats.syntax.traverse._
val funcs: List[String => String] = List(identity, _.reverse)
val f = funcs.sequenceU
在 Haskell中,它的参数的外部类型构造函数sequence
需要一个实例,内部类型构造函数需要一个实例。Cats几乎是一样的——<code>Traversable 被调用(因为这个名字已经被标准库使用了),它需要一个实例而不是(这是一个更准确的约束——Haskell只需要一个 monad 实例,因为历史原因) .Traversable
Monad
sequence
Traverse
Traversable
Applicative
Monad
sequence
如果你愿意,你可以 import cats.implicits._
,但这会带来很多其他的东西。上面的导入提供了您需要的最小类型类实例和语法扩展。
你可以使用f
, 这是一个String => List[String]
, 像这样:
scala> f("test")
res0: List[String] = List(test, tset)
请注意,如果您使用的是 2.12.1 并-Ypartial-unification
启用了编译器标志,则可以只写.sequence
,而不是.sequenceU
. 为什么需要U
早期的 Scala 版本说来话长——请参阅我的博文以获得解释。