我在想如何将f x = zip x (tail x)
改写成点-free形式。于是我使用了pointfree程序,得到的结果是f = ap zip tail
,其中ap
是Control.Monad中的函数。
我不理解这个点-free定义是如何工作的。如果可以从类型的角度理解它,我希望我能理解它。
import Control.Monad (ap)
let f = ap zip tail
let g = ap zip
:info ap zip tail f g
ap :: Monad m => m (a -> b) -> m a -> m b
-- Defined in `Control.Monad'
zip :: [a] -> [b] -> [(a, b)] -- Defined in `GHC.List'
tail :: [a] -> [a] -- Defined in `GHC.List'
f :: [b] -> [(b, b)] -- Defined at <interactive>:3:5
g :: ([a] -> [b]) -> [a] -> [(a, b)]
-- Defined at <interactive>:4:5
通过观察表达式ap zip tail
,我会认为zip
是 ap
的第一个参数,而tail
是ap
的第二个参数。
Monad m => m (a -> b) -> m a -> m b
\--------/ \---/
zip tail
但这是不可能的,因为zip
和tail
的类型与函数ap
所需的类型完全不同。即使考虑到列表是某种单子。
a
变成了zip类型的[a] -> [b]
。如果是这种情况,那么支配它的统一规则(如果这是正确的词)是什么? - user7610ap zip tail :: Monad ((->) [b]) => [b] -> [(b, b)]
... 没有太多的调查,我会说Monad ((->) [b])
是你想要了解的。 我认为http://learnyouahaskell.com/for-a-few-monads-more#reader可能会帮助你理解这里发生了什么。 - Adam Wagnerzip <*> tail
是等价的,而且看起来更漂亮。 - daniel gratzerf x = zip x (tail x)
,可能是因为它是唯一一种让我立刻看到作者意图的形式。 - user7610