函数的函数结构

时间:2016-02-20 14:01:46

标签: haskell functor

我很难理解函数的函数结构。

我想我对ghci有一个线索:

Prelude> :t (->)
(->) :: * -> * -> *

因此,如果需要一种类型,则应用它( - >)将具有所需类型* - > *,这对于Functor定义是可以的。

但是我找不到我们可以写的原因:

Prelude> let test = fmap (+1) (+1)
Prelude> :t test
test :: Integer -> Integer

处理( - >)时使用的仿函数实例是什么?它看起来像什么?

它做什么?我的意思是我不理解第一个(+1)对第二个函数(+1)

的影响

1 个答案:

答案 0 :(得分:4)

你的推理是完全正确的 - 现在你只需要考虑这对你的算子实例意味着什么。

通常您的仿函数 f fmap类型是这样的:

fmap :: (a -> b) -> (f a -> f b)

但现在您有(->) r(您可以将其视为r -> *)而不是f

所以,如果你只是填写这个,你得到:

fmap :: (a -> b) -> ((r -> a) -> (r -> b))

如果你仔细阅读这意味着给定一个函数g :: a -> b fmap g将能够函数f :: r -> a转换为函数{{1} }}

fmap g f :: r -> b的仿函数实例如下所示:

(->) r

当你第一次看到它时有点奇怪,但它基本上只是函数组合(或者如果你喜欢源类型是常数并且你fmap应用你的函数的结果)

所以在示例中你会得到:

instance Functor ((->) r) where
   fmap g f = \ r -> g (f r) -- = g . f

所以你得到一个为结果加2的函数。

但如果你看一下,你可能会看到更多

fmap (+1) (+1)
{ def. (+1) }
= fmap (+1) (\r -> r+1)
{ fmap here }
= \r -> (+1) (r+1)
{ definition (+1) }
= \r -> (\a -> a+1) (r+1)
{ lambda application }
= \r -> (r+1) + 1
= (+1) . (+1) -- if you like
{ which is the same as }
= \r -> r+2
= (+2) -- if you like

所以你看

fmap (*2) (+1)
{ def. (+1) }
= fmap (*2) (\r -> r+1)
{ fmap here }
= \r -> (*2) (r+1)
{ definition (*2) }
= \r -> (\a -> a*2) (r+1)
{ lambda application }
= \r -> (r+1) * 2
= \r -> r*2+2
= (*2) . (+1) -- if you like

顺便提一下,如果您点击Implementation

中的来源链接,就可以查看hackage doc本身

那里只是

fmap g f = g . f