4

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

4

1 回答 1

5

它或多或少完全相同,只是语法有点不同,您需要一些额外的导入,并且通用版本不那么方便,因为 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 实例,因为历史原因) .TraversableMonadsequenceTraverseTraversableApplicativeMonadsequence

如果你愿意,你可以 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 版本说来话长——请参阅我的文以获得解释。

于 2017-01-26T19:52:49.270 回答