【问题标题】:Applicative instance for free monad免费 monad 的应用实例
【发布时间】:2014-04-03 00:53:24
【问题描述】:

在试图找到一个可以逐步执行/允许线程的haskell 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 的应用函子。 对我来说,应用函子在概念上比单子更难。为了更好地理解 applicative functors,我喜欢在不诉诸 ap 的情况下拥有 applicative 实例。

<*> 的第一行很简单:

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&lt;*&gt;如何在基本术语中定义Roll f &lt;*&gt; x

【问题讨论】:

    标签: haskell applicative free-monad


    【解决方案1】:

    这样可以吗?

    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 的标志:计算的结构是固定的,因此值取决于值,但动作不。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-10
      相关资源
      最近更新 更多