适用于免费monad的应用程序实例

当试图找到一个可以逐步执行/允许线程的哈斯克尔monad时,我发现了免费的monad

data Free f a = Return a | Roll (f (Free f a))

与它的monad实例

instance (Functor f) => Monad (Free f) where
  return = Return
  Return x    >>= f = f x
  Roll action >>= f = Roll $ fmap (>>= f) action

和它的函子实例

instance (Functor f) => Functor (Free f) where
  fmap f (Return x) = Return (f x)
  fmap f (Roll   x) = Roll $ fmap (fmap f) x

我知道每个monad都是pure = return(<*>) = ap的应用函子。 对我而言,应用函数在概念上比单子更难。 为了更好地理解应用函数,我喜欢在不使用ap情况下应用实例。

第一行<*>很简单:

instance (Applicative f) => Applicative (Free f) where
  pure = Return
  Return f <*> x = fmap f x -- follows immediately from pure f <*> x = f <$> x
--Roll   f <*> x = Roll $ (fmap ((fmap f) <*>)) x -- wrong, does not type-check

如何用fmap<*>定义Roll f <*> x的基本术语?


这会做什么?

instance (Functor f) => Applicative (Free f) where
  pure = Return
  Return f  <*> as  = fmap f as
  Roll faf  <*> as  = Roll (fmap (<*> as) faf)

计划只是在产生函数的树的叶子上执行,因此对于Return ,我们通过将函数应用于由参数动作产生的所有参数值来执行操作。 对于Roll ,我们只是对所有的子动作做我们打算做的整体动作。

最重要的是,我们在达到Return时所做的事情已经在我们开始之前就已经确定了。 根据我们在树中的位置,我们不会改变我们的计划。 这是Applicative的特点:计算的结构是固定的,所以值取决于值,但行为不取决于值。

链接地址: http://www.djcxy.com/p/47695.html

上一篇: Applicative instance for free monad

下一篇: Applying Semantics to Free Monads