Scala中的Reader monad:return,local和sequence

时间:2016-07-22 10:40:29

标签: scala monads scalaz reader-monad

我正在使用scalaz库提供的Scala中的Reader monad。我熟悉这个monad as defined in Haskell。问题是我找不到与returnlocalsequence(等等)相当的功能。

目前我使用的是我不喜欢的构造,因为我重复自己或使我的代码模糊不清。

关于return,我目前正在使用:

Reader{_ => someValue}

我宁愿使用类似unit(someValue)的构造,但我在互联网上找不到任何东西。像this one这样的教程使用上面的方法,我认为这不是最优的。

关于local我还必须做类似的事情:而不是输入类似的内容: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上使用sequence操作。

scalaz或类似的库上有没有更好的翻译这些构造到Scala?我没有与Scala的任何功能库结合,因此使用其他库的任何解决方案都可以,但我更倾向于使用scalaz,因为我已经使用它实现了我的代码。

1 个答案:

答案 0 :(得分:1)

为了简单起见,我填写了一些类型。使用泛型类型将它们更改为defs应该仍然有效。 我还提取了ReaderInt类型,以避免与lambda类型混淆。

return / pure / point

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],其中F是你的应用。

本地

不确定,它会回答您的问题,但Kleislilocal方法。

val f: String ⇒ Int = _.length
val alwaysEleven = alwaysHello local f

<强>测序

同样,您可以自由选择使用syntax或明确指定类型类。

  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]    

我不想使用sequenceUUnapply使用G typelcass来推断04504a8b6c715f933110c8c970a8f6ad类型,因为有时scala会遇到纠正正确问题的麻烦。 而且我个人并不认为自己投入某些类型会很麻烦。

可能值得研究cats,尽管它还没有多少。