使用Scala Cats

时间:2017-01-26 19:35:37

标签: scala scalaz scala-cats

在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的实现?

1 个答案:

答案 0 :(得分:5)

它或多或少完全相同,除了语法稍有不同,你需要一些额外的导入,并且通用版本不方便,因为Scala的String不仅仅是一个别名字符列表:

import cats.instances.function._, cats.instances.list._, cats.syntax.traverse._

val funcs: List[String => String] = List(identity, _.reverse)

val f = funcs.sequenceU

在Haskell中sequence需要一个Traversable实例作为其参数的外部类型构造函数,并且Monad实例需要内部类型构造函数。猫的sequence几乎相同 - Traversable被称为Traverse(因为标准库已经使用了名称Traversable),它需要Applicative实例而不是Monad(这是一个更准确的约束 - Haskell的sequence仅因历史原因需要monad实例。)

如果你想要,你可以导入cats.implicits._,但这会带来很多其他的东西。上面的导入提供了所需的最小类型类实例和语法扩展。

您可以使用f String => List[String],如下所示:

scala> f("test")
res0: List[String] = List(test, tset)

请注意,如果您使用的是2.12.1且启用了-Ypartial-unification编译器标志,则只能编写.sequence,而不是.sequenceU。为什么你需要早期Scala版本的U是一个很长的故事 - 请参阅我的blog post here以获得解释。