加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

在Scala中组成免费monad

发布时间:2020-12-16 08:55:12 所属栏目:安全 来源:网络整理
导读:我想我明白Free monad是什么.我希望我也理解函子组成了monad do not,即如果M1和M2是monad,则M1 [M2]不一定是monad. 我的问题是: 自由单子组成吗? 假设我们有仿函数F1和F2以及它们的组成F1 [F2].假设我们还有Free1和Free2 – F1和F2的免费单子.我们可以用Fr
我想我明白Free monad是什么.我希望我也理解函子组成了monad do not,即如果M1和M2是monad,则M1 [M2]不一定是monad.

我的问题是:

>自由单子组成吗?
>假设我们有仿函数F1和F2以及它们的组成F1 [F2].假设我们还有Free1和Free2 – F1和F2的免费单子.我们可以用Free1和Free2为F1 [F2]定义一个免费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]].

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读