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
我们可以复制它的定义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)
(为了清楚起见,添加了一些多余的括号。)
如果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)
当然这评价了f和v顺序,因为它的单子,这是什么单子做。如果该应用程序没有按顺序执行操作,那么它不是单子。
当然,现代Haskell可以用另一种方式定义此Applicative类型:typeclass是它的子集,Functor因此,如果您有a Functor并且可以定义,(<*>)则可以创建一个Applicative实例。Monad依次定义为的子集Applicative,因此,如果您有一个Applicative实例并且可以定义,(>>=)则可以创建一个Monad实例。但是你不能定义(>>=)来讲(<*>)。
有关更多详细信息,请参见Typeclassopedia。
| 归档时间: |
|
| 查看次数: |
87 次 |
| 最近记录: |