在Scala中组成免费monad
我想我明白Free monad是什么.我希望我也理解函子组成了monad
do not,即如果M1和M2是monad,则M1 [M2]不一定是monad.
我的问题是: >自由单子组成吗? 解决方法
希望我能回答你的问题:
自由单子组成吗? 不会出于与“普通”单子相同的原因.要编写monadic绑定,我们需要了解有关底层monad的信息,或者关于自由monad案例中的底层函子. 希望Haskell语法不会吓到你太多: type X f g a = Free f (Free g a) bind :: X f g a -> (a -> X f g b) -> X f g b bind (Pure (Pure x)) k = k x bind (Pure (Free f)) k = error "not implemented" bind _ = error "we don't even consider other cases" 在第二种情况下,我们有f :: g(Free g a)和k :: a – >免费f(免费g b).我们可以fmap,因为这是我们唯一可以做的事情: bind (Pure (Free f)) k = let kf = fmap (fmap k) f -- fmapping inside g ° Free g in = error "not implement" 当我们需要Free f(Free g b)时,kf的类型为:g(Free g(Free f(Free g b))).您将遇到与为任何Compose m1 m2编写monad实例时相同的问题,我们需要将“绑定层”从g-g-f-g重新排序到f-g-g-g,为了进行这种换向,我们需要了解更多关于f和g的信息. 如果你想看到上面的Scala版本,请发表评论.但它会更加模糊:( 我们可以用Free1和Free2定义F1 [F2]的免费monad 换句话说: type Free1[A] = Free[F1,A] type Free2[A] = Free[F2,B] type FreeDist[A] = Free1[Free2[A]] = Free[F1,Free[F2,A]] type FreeComp[A] = Free[F1[F2[_]],A] 我们可以写一个从FreeDist [A]到FreeComp [A]的monad同态(一个很好的映射)吗?我们不能,出于与前一部分相同的原因. Scala版本 Scalaz有Free的子类的私有定义,所以我必须自己实现Free以拥有一个“可运行”的例子.部分代码从http://eed3si9n.com/learning-scalaz/Free+Monad.html中删除 Scala中Free的第一个最简单的定义: import scala.language.higherKinds trait Functor[F[_]] { def map[A,B](x: F[A])(f: A => B): F[B] } sealed trait Free[F[_],A] { def map[B](f: A => B)(implicit functor: Functor[F]): Free[F,B] def flatMap[B](f: A => Free[F,B])(implicit functor: Functor[F]): Free[F,B] } case class Pure[F[_],A](x: A) extends Free[F,B] = Pure[F,B](f(x)) def flatMap[B](f: A => Free[F,B] = f(x) } case class Bind[F[_],A](x: F[Free[F,A]]) extends Free[F,A] { def map[B](f: A => B)(implicit functor: Functor[F]): Free[F,B] = Bind { functor.map[Free[F,A],Free[F,B]](x) { y => y.map(f) } } // omitted def flatMap[B](f: A => Free[F,B] = ??? } 使用它我们可以将Haskell示例转换为Scala: type X[F[_],G[_],A] = Free[F,Free[G,A]] // bind :: X f g a -> (a -> X f g b) -> X f g b def xFlatMap[F[_],A,B](x: X[F,G,k: A => X[F,B])(implicit functorG: Functor[G]): X[F,B] = x match { case Pure(Pure(y)) => k(y) case Pure(Bind(f)) => { // kf :: g (Free g (Free f (Free g b))) val kf: G[Free[G,B]]]] = functorG.map(f) { y => y.map(k) } // But we need Free[F,B]] ??? } // we don't consider other cases case _ => ??? } 结果是一样的,我们不能使类型匹配,我们需要以某种方式将Free [G,Free [F,A]]转换为Free [F,Free [G,A]]. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |