haskell - 如何派生此函数的类型:
问题描述
我正在努力提高玩“俄罗斯方块”的能力。我有以下功能:
(=<<) :: Monad m => (a -> m b) -> m a -> m b
zip :: [a] -> [b] -> [(a, b)]
GHCI 告诉我:
(zip =<<) :: ([b] -> [a]) -> [b] -> [(a, b)]
我很难弄清楚如何从前两个中得出最终的签名。我的直觉(因为没有更好的词)是说 is 的第一个论点=<<
以a -> mb
某种方式与 的签名相协调zip
,然后它应该全部从那里掉出来。但我无法理解如何实现这一飞跃。它可以分解为一系列易于遵循的步骤吗?
解决方案
(zip =<<)
等价于(>>= zip)
,这可能使其更具可读性。正如您正确观察到的那样,无论哪种方式,都zip
占据了这些功能中的位置。(a -> m b)
要进行的一种更直观的转换是考虑=<<
. 它“接受”两个参数,所以如果我们将它应用于一个,我们应该只剩下一个。因此,签名([b] -> [a]) -> [b] -> [(a, b)]
是一元函数!
(zip =<<) :: ([b] -> [a]) -> ([b] -> [(a, b)])
------------ -----------------
m a' m b'
那是什么m
?Monad 实例存在于函数(r ->)
(或,或者,(->) r
)。所以在这种情况下r :: [b]
(因此m :: ([b] ->)
)a' :: [a]
和b' :: [(a, b)]
。
因此,zip
正如我们在开始时断言的那样:
a' -> m b' -- substitute [(a,b)] for b'
a' -> m [(a, b)] -- substitute [a] for a'
[a] -> m [(a, b)] -- substitute ([b] ->) for m
[a] -> ([b] -> [(a,b)])
[a] -> [b] -> [(a,b)]
推荐阅读
- kdb - KDB Q 和 jupyterlab 不在桃子上使用奴隶
- python - 在 django 模型中,提供一组默认字段,但也允许用户添加自己的字段
- nginx - Nginx 转发基于来自另一个服务的响应
- openssl - 使用 PHPMailer / SMTP / LimeSurvey 拒绝权限
- sql-server - 如何在两个数字之间生成一系列字母数字?
- angular - 如何在 Angular 7 中为 URL 路由添加前缀('/admin')
- json - react native - 尝试从存储在 localstorage 中的 json 对象呈现单个值
- javascript - 测试 react.js 应用程序时无法将鼠标事件发送到选定元素
- node.js - 如何使用 xero 节点包装器 xero-node 更新联系人的帐号?
- apache-flink - 如何为流以外的flink表设置并行度