如何定义绑定方面的适用?

Paw*_*mar 2 monads haskell functor applicative

在Haskell中,Applicatives被认为比Functor更强大,这意味着我们可以使用Applicative来定义Functor,例如

-- Functor
fmap :: (a -> b) -> f a -> f b
fmap f fa = pure f <*> fa
Run Code Online (Sandbox Code Playgroud)

和Monads被认为比Applicatives&Functors更强大。

-- Functor
fmap :: (a -> b) -> f a -> f b
fmap f fa = fa >>= return . f

-- Applicative
pure :: a -> f a
pure = return

(<*>) :: f (a -> b) -> f a -> f b
(<*>) = ???  -- Can we define this in terms return & bind? without using "ap" 
Run Code Online (Sandbox Code Playgroud)

我读过Monad是用于排序动作的。但是我觉得Monad唯一能做的就是Join或Flatten,其余功能来自Applicatives。

join :: m (m a) -> m a
-- & where is the sequencing in this part? I don't get it.
Run Code Online (Sandbox Code Playgroud)

如果Monad确实用于排序动作,那么我们如何定义Applicatives(不被认为严格地按顺序运行某种并行计算)?

由于monads是endofunctors类别中的Monoids。也有可交换的monoid,不一定必须按顺序工作。这意味着可交换Monoid的Monad实例也需要排序吗?

编辑: 我发现了一个很好的页面 http://wiki.haskell.org/What_a_Monad_is_not

chi*_*chi 5

我们可以复制它的定义ap并对其进行脱糖:

ap f a = do
   xf <- f
   xa <- a
   return (xf xa)
Run Code Online (Sandbox Code Playgroud)

因此,

f <*> a = f >>= (\xf -> a >>= (\xa -> return (xf xa)))
Run Code Online (Sandbox Code Playgroud)

(为了清楚起见,添加了一些多余的括号。)


Pau*_*son 5

如果Monad确实用于排序动作,那么我们如何定义Applicatives(不被认为严格地按顺序运行某种并行计算)?

不完全的。所有monads都是appadatives,但是只有一些appatives是monads。因此,给定一个monad,您始终可以根据bind和定义一个应用实例return,但是如果您拥有的只是该应用实例,那么就不能在没有更多信息的情况下定义一个monad。

monad的适用实例如下所示:

instance (Monad m) => Applicative m where
   pure = return
   f <*> v = do
      f' <- f
      v' <- v
      return $ f' v'
Run Code Online (Sandbox Code Playgroud)

当然这评价了fv顺序,因为它的单子,这是什么单子做。如果该应用程序没有按顺序执行操作,那么它不是单子。

当然,现代Haskell可以用另一种方式定义此Applicative类型:typeclass是它的子集,Functor因此,如果您有a Functor并且可以定义,(<*>)则可以创建一个Applicative实例。Monad依次定义为的子集Applicative,因此,如果您有一个Applicative实例并且可以定义,(>>=)则可以创建一个Monad实例。但是你不能定义(>>=)来讲(<*>)

有关更多详细信息,请参见Typeclassopedia

  • 排序是monad的“应用”,而不是定义功能。常规函数组合还实现了一种排序方式:在“ f(gx)”中,您必须在“ f”之前调用“ g”。 (2认同)