解释免费monad列表与解释列表中的免费monad

时间:2018-03-05 21:41:14

标签: scala monads scalaz

我正在学习函数式编程,并且有一些(可能很明显,但不适合我:))关于monad的问题。每个monad都是一个应用函子。应用仿函数又可以定义为高级类型,如下所示(pure方法省略):

trait ApplicativeFunctor[F[_]]{
   def ap[A](fa: F[A])(f: F[A => B]): F[B]
}

据我所知,这个类型类意味着我们可以采用F[A]F[B]和函数(A, B) => C两个值并构造F[C]

此属性使我们能够构建列表反转功能:

def reverseApList[F[_]: ApplicativeFunctor, A](lst: List[F[A]]): F[List[A]] 

我们有

trait SomeType[A]

现在考虑

type MyFree[A] = Free[SomeType, A] 
val nt: NaturalTransformation[SomeType, Id]
val lst: List[MyFree[Int]]

问题: 为什么lst.map(_.foldMap(nt))reverseApList(lst).foldMap(nt)相同?是应用仿函数法还是其他原因?你能解释一下吗?

1 个答案:

答案 0 :(得分:8)

它遵循Traversable算子的定律。

首先,要意识到_.foldMap(nt)本身就是从MyFreeId的自然转换。此外,通过对自由monad的含义的定义,它必须是 monad同态 1 (对于任何nt)。< / p>

让我们从您的

开始
reverseApList(lst).foldMap(nt)

也可以写成

lst.sequence.foldMap(nt)

现在我们将应用naturality law of Traversable functors_.foldMap(nt)作为自然转换nat。为了适用它,我们的自然变换必须是 applicative homomorphism ,由the two extra conditions表示。但我们已经知道,我们的自然变换是一个单子同态,它比应用同态更强(保留更多的结构)。因此,我们可以继续适用这项法律并获得

lst.map(_.foldMap(nt)).sequence : Id[List[Int]]

现在只使用链接的scalaz文件中的规则,可证明(尽管以迂回方式),最后sequenceId实际上是无操作。我们得到

lst.map(_.foldMap(nt))          : List[Id[Int]]

这是我们想要展示的内容。

1 :自然变换h: M ~> N是monad同态,如果它保留了monadic结构,即它是否满足

  • 代表任何a: A
    h(Monad[M].point[A](a)) = Monad[N].point[A](a)
  • 适用于任何ma: M[A]f: A => M[B]
    h(ma.flatMap(f)) = h(ma).flatMap(a => h(f(a)))