Scala中的读者monad:返回,本地和序列
我正在使用
scalaz库提供的Scala中的Reader monad.我熟悉这个monad
as defined in Haskell.问题是我找不到与return,local和sequence(等等)相当的函数.
目前我使用的是我不喜欢的结构,因为我正在重复自己或使我的代码有点模糊. 关于回归,我目前正在使用: Reader{_ => someValue} 我宁愿只使用像unit(someValue)这样的构造,但我在互联网上找不到任何东西.像this one这样的教程使用上面的方法,我认为这不是最优的. 关于本地我也必须做类似的事情:而不是输入类似的东西:local f myReader我必须展开它的定义: Reader{env => myReader.run(f(env)) 最后,序列更接近我的期望(作为一个Haskell难民做Scala): readers: List[Reader[Env,T]] readerTs: Reader[Env,List[T]] = readers.sequenceU 我对这个实现的问题是,对于Scala而言,它是sequenceU的类型 final class TraverSEOps[F[_],A] private[syntax](val self: F[A])(implicit val F: Traverse[F]) extends Ops[F[A]] { //... def sequenceU(implicit G: Unapply[Applicative,A]): G.M[F[G.A]] 看起来很晦涩,看起来像是黑魔法.理想情况下,我想在Monads上使用序列操作. scalaz或类似的库上有没有更好的翻译这些构造到Scala?我没有与Scala的任何功能库结合,所以使用其他库的任何解决方案都可以,尽管我更愿意使用scalaz,因为我已经使用它实现了我的代码. 解决方法
为了使事情更简单,我填写了一些类型.使用泛型类型将它们更改为defs应该仍然有效.
我还提取了ReaderInt类型,以避免与lambda类型混淆. 返回/纯/点 Scala没有自动类型类分辨率,因此您需要隐式提供它们.对于Kleisli(作为读者的monad变换器), 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] 所以作为一般规则,你 本地 val f: String ? Int = _.length val alwaysEleven = alwaysHello local f 测序 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 typelcass来推断G类型,因为有时scala在找出正确的类型时会遇到麻烦. 它可能值得研究cats,尽管它还没有多少. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |