Scala中自由单子的合成
我想我明白什么是免费的。我希望我也能理解,函子只构成单子,也就是说,如果Scala中自由单子的合成,scala,functional-programming,functor,free-monad,Scala,Functional Programming,Functor,Free Monad,我想我明白什么是免费的。我希望我也能理解,函子只构成单子,也就是说,如果M1和M2是单子,那么M1[M2]不一定是单子 我的问题是: Free单子组成吗 假设我们有函子F1和F2及其组合F1[F2]。假设我们还有Free1和Free2--Free单子,用于F1和F2。我们能用Free1和Free2为F1[F2]定义一个Free单子吗 希望我能回答你的问题: 自由单子作曲吗? 不,因为和“正常”单子不一样的原因。要编写一元绑定,我们需要了解一些关于底层单体的信息,或者自由单体情况下的底层函子的信
M1
和M2
是单子,那么M1[M2]
不一定是单子
我的问题是:
单子组成吗Free
- 假设我们有函子
和F1
及其组合F2
。假设我们还有F1[F2]
和Free1
--Free2
单子,用于Free
和F1
。我们能用F2
和Free1
为Free2
定义一个F1[F2]
单子吗李>Free
- 希望我能回答你的问题:
自由单子作曲吗?
不,因为和“正常”单子不一样的原因。要编写一元绑定,我们需要了解一些关于底层单体的信息,或者自由单体情况下的底层函子的信息
希望Haskell语法不会让您太害怕:
在第二种情况下,我们有X f g a型=自由f(自由g a) 绑定::X f g a->(a->X f g b)->X f g b 绑定(纯(纯x))k=kx 绑定(纯(自由f))k=错误“未实现” 绑定=错误“我们甚至不考虑其他情况”
和f::g(freega)
。我们可以k::a->freeff(freegb)
,因为这是我们唯一能做的事情:fmap
当我们需要时,bind(纯(自由f))k=let kf=fmap(fmap k)f--fmapping in g∘ 自由g in=错误“未实现”
的类型将是:kf
。您将遇到与为任何g(Free g(Free f(Free gb))
编写monad实例时相同的问题,我们需要将“绑定层”从composem1m2
重新排序为g-g-g
,要进行转换,我们需要了解更多关于f-g-g
和f
如果您想查看上面的Scala版本,请发表评论。但这将更加模糊:( 我们能为F1[F2]定义一个只有Free1和Free2的自由单子吗 换言之:g
我们可以写一个从type Free1[A]=Free[F1,A] 类型Free2[A]=Free[F2,B] 键入FreeDist[A]=Free1[Free2[A]=Free[F1,Free[F2,A]] 输入FreeComp[A]=Free[F1[F2[]],A]
到FreeDist[a]
的单子同态(一个很好的映射)吗?我们不能,原因与前面的部分相同FreeComp[a]
Scala版本 Scalaz有
的子类的私有定义,所以我必须自己实现Free
来创建一个“可运行”的示例 Scala中Free
的第一个最简单定义:Free
使用该工具,我们可以将Haskell示例转换为Scala: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, A] { def map[B](f: A => B)(implicit functor: Functor[F]): Free[F, B] = Pure[F, B](f(x)) def flatMap[B](f: A => Free[F, B])(implicit functor: Functor[F]): 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])(implicit functor: Functor[F]): Free[F, B] = ??? }
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[_], G[_], A, B](x: X[F, G, A], k: A => X[F, G, B])(implicit functorG: Functor[G]): X[F, G, 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, Free[F, Free[G, B]]]] = functorG.map(f) { y => y.map(k) } // But we need Free[F, Free[G, B]] ??? } // we don't consider other cases case _ => ??? }
结果是一样的,我们无法使类型匹配,我们需要将
转换为Free[G,Free[F,A]]
。感谢您提供详细的答案。我将使用Haskell符号进行管理。我看不懂Haskell,我希望看到Scala版本。(我还将做一个实验,因为自由似乎应该让我们进行交换,可能是以一种非均匀的方式)。另外,如果我们使用自由单子来实现可扩展的效果,我们可以合成效果,这可以看作是合成不同的单子。但这有点不同,需要另一个答案。Free[F,Free[G,A]]