haskell - 如何定义绑定方面的应用?
问题描述
在 Haskell Applicatives 被认为比 Functor 更强大,这意味着我们可以使用 Applicative 来定义 Functor
-- Functor
fmap :: (a -> b) -> f a -> f b
fmap f fa = pure f <*> fa
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"
我读过 Monads 用于排序操作。但我觉得 Monad 唯一能做的就是 Join 或 Flatten,它的其余功能来自 Applicatives。
join :: m (m a) -> m a
-- & where is the sequencing in this part? I don't get it.
如果 Monad 真的是为了顺序动作,那我们怎么能定义 Applicatives (不被认为是严格按顺序操作的,某种并行计算)?
由于单子是内函子类别中的 Monoids。也有可交换幺半群,它们不一定需要按顺序工作。这意味着 Commutative Monoids 的 Monad 实例也需要排序?
编辑: 我发现了一个很棒的页面 http://wiki.haskell.org/What_a_Monad_is_not
解决方案
我们可以复制它的定义ap
并对其进行脱糖:
ap f a = do
xf <- f
xa <- a
return (xf xa)
因此,
f <*> a = f >>= (\xf -> a >>= (\xa -> return (xf xa)))
(为清楚起见,添加了一些多余的括号。)
推荐阅读
- vue.js - 更新数组 vuex 中的现有对象
- react-native - 反应原生 youtube - 组件不可见
- javascript - 智能 DOM 插入(保留子元素的样式)
- spring-boot - 如何从 websocket 客户端(浏览器)使用服务器端的消息?
- java - 在 chrome 最新版本中使用 selenium 处理打印预览窗口
- c# - 分页时如何将默认排序从主键更改为另一个字段?
- unit-testing - 如何为包含 RxJava/RxAndroid 的 ViewModel 编写单元测试
- javascript - 如何将此函数的内容返回给客户端?
- sql - 跨多个层的 SQL 循环/递归
- git - Git push Refspecs:`refs/heads/*:refs/heads/origin` vs `refs/heads/*:refs/heads/*`