Bri*_*ian 16 monads haskell side-effects applicative
我觉得这个问题很傻,但是我已经想到了一段时间,我找不到任何答案.
所以问题是:为什么应用仿函数有副作用,但仿函数不能?
也许他们可以而且我从未注意到......?
Pet*_*lák 26
Functors没有效果是不正确的.每一个Applicative(每Monad经WrappedMonad)是Functor.主要的区别是,Applicative和Monad给你的工具如何与这些效果,如何将它们结合起来的工作.大致
Applicative 允许您对效果进行排序并将值组合在一起.Monad 此外,您还可以根据前一个效果确定下一个效果.但是Functor只允许你修改里面的值,它不会给工具做任何有效的事情.所以,如果事情仅仅是Functor,不Applicative,这并不意味着它没有影响.它只是没有一种机制如何以这种方式组合它们.
更新:举个例子,考虑一下
import Control.Applicative
newtype MyF r a = MyF (IO (r, a))
instance Functor (MyF r) where
fmap f (MyF x) = MyF $ fmap (fmap f) x
Run Code Online (Sandbox Code Playgroud)
这显然是一个Functor带有效果的实例.只是我们没有办法如何定义符合这些效果的操作 Applicative.除非我们施加一些额外的约束r,否则无法定义Applicative实例.
sha*_*ang 25
这个答案有点过分简化,但如果我们将副作用定义为计算受到先前计算的影响,很容易看出Functor类型类不足以产生副作用,因为无法链接多个计算.
class Functor f where
fmap :: (a -> b) -> f a -> f b
Run Code Online (Sandbox Code Playgroud)
仿函数唯一能做的就是通过一些纯函数来改变计算的最终结果a -> b.
但是,应用程序函数添加了两个新函数,pure和<*>.
class Functor f => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
Run Code Online (Sandbox Code Playgroud)
这<*>是至关重要的区别,因为它允许我们链接两个计算:(
f (a -> b)产生函数f a的计算)和提供应用函数的参数的计算.使用pure并且<*>可以定义例如
(*>) :: f a -> f b -> f b
Run Code Online (Sandbox Code Playgroud)
这简单地链接两个计算,从第一个计算中丢弃最终结果(但可能应用"副作用").
简而言之,它是链计算的能力,这是计算中可变状态等效果的最低要求.
| 归档时间: |
|
| 查看次数: |
1888 次 |
| 最近记录: |