为了让事情变得简单,我填写了一些类型。将它们更改为具有泛型类型的 def 应该仍然有效。
我还提取了ReaderInt
type,以避免与 lambda 类型混淆。
返回/纯/点
Scala 没有自动类型类解析,因此您需要隐式提供它们。为了Kleisli
(作为读者的 monad 转换器),Kleisli[Id, ?, ?]
足够
implicit val KA = scalaz.Kleisli.kleisliIdApplicative[Int]
type ReaderInt[A] = Kleisli[Id.Id, Int, A]
val alwaysHello = KA.point("hello")
或使用导入的语法:
import scalaz.syntax.applicative._
val alwaysHello = "hello".point[ReaderInt]
所以作为一般规则,你
1)导入应用实例,通常位于scalaz.std.something.somethingInstance
2) import scalaz.syntax.something._
3)然后你可以写x.point[F]
, where F
是你的应用。
local
不确定它是否回答了你的问题,但是Kleisli
has a local
method.
val f: String ⇒ Int = _.length
val alwaysEleven = alwaysHello local f
测序
同样的,你可以自由选择使用syntax
for 或 显式指定类型类。
import scalaz.std.list.listInstance
val initial: List[ReaderInt[String]] = ???
val sequenced: ReaderInt[List[String]] = Traverse[List].sequence[ReaderInt, String](initial)
import scalaz.syntax.traverse._
val z = x.sequence[ReaderInt, String]
我宁愿不使用sequenceU
,它使用Unapply
typelcas 来推断G
类型,因为有时 scala 很难找出正确的类型。
而且我个人并不觉得自己输入一些类型很混乱。
可能值得研究一下cats https://github.com/typelevel/cats,虽然还没有太多。