Haskell 函数的功能结构

Haskell 函数的功能结构,haskell,functor,Haskell,Functor,我很难理解函数的函数结构 我想我对ghci有一个线索: Prelude> :t (->) (->) :: * -> * -> * 所以,如果给一个类型加上feed,应用它(->)将得到所需的种类*->*,这对于函子定义来说是可以的 但是我找不到我们可以写的原因: Prelude> let test = fmap (+1) (+1) Prelude> :t test test :: Integer -> Integer 处理(->)时使用的函子实

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

我想我对ghci有一个线索:

Prelude> :t (->)
(->) :: * -> * -> *
所以,如果给一个类型加上feed,应用它(->)将得到所需的种类*->*,这对于函子定义来说是可以的

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

Prelude> let test = fmap (+1) (+1)
Prelude> :t test
test :: Integer -> Integer
处理(->)时使用的函子实例是什么?它看起来像什么


它有什么作用?我的意思是我不明白第一个(+1)对第二个函数(+1)的影响。

你的推理是绝对正确的-现在你只需要想想这对你的函子实例意味着什么

通常您的函子
f
fmap
类型如下:

fmap :: (a -> b) -> (f a -> f b)
instance Functor ((->) r) where
   fmap g f = \ r -> g (f r) -- = g . f
但是现在你有了
(>)r
(你可以把它看作
r->*
)而不是
f

因此,如果您只需填写以下内容,您将得到:

fmap :: (a -> b) -> ((r -> a) -> (r -> b))
如果您仔细阅读,这意味着给定一个函数
g::a->b
fmap g
将能够将函数
f::r->a
转换为函数
fmap g f::r->b


(>)r
的函子实例如下所示:

fmap :: (a -> b) -> (f a -> f b)
instance Functor ((->) r) where
   fmap g f = \ r -> g (f r) -- = g . f
第一次看到它时有点奇怪,但它基本上只是函数合成(或者如果您喜欢源类型是常量,并且您可以快速映射应用函数的结果)

因此,在示例中,您可以得到:

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
所以你得到一个函数,在结果中加2

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

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
你看

fmap g f = g . f

顺便说一句,如果您单击

就在那里

instance Functor ((->) r) where
    fmap = (.)