函数的函数结构
Functorial structure of functions
我很难理解函数的函数结构。
我想我对 ghci 有所了解:
Prelude> :t (->)
(->) :: * -> * -> *
因此,如果输入一个类型,对其应用 (->) 将得到所需的类型 * -> *,这对于 Functor 定义是可以的。
但是我找不到我们可以写的原因:
Prelude> let test = fmap (+1) (+1)
Prelude> :t test
test :: Integer -> Integer
处理 (->) 时使用的仿函数实例是什么?它看起来像什么?
它有什么作用?我的意思是我不明白第一个 (+1) 对第二个函数 (+1)
的影响
您的推理完全正确 - 现在您只需考虑这对您的仿函数实例意味着什么。
通常你的 functors 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
到函数 fmap g f :: r -> b
(->) r
的仿函数实例如下所示:
instance Functor ((->) r) where
fmap g f = \ r -> g (f r) -- = g . f
当你第一次看到它时有点奇怪,但它基本上只是函数组合(或者如果你喜欢 source-type 是常量并且你 fmap 应用你的函数的结果)
所以在这个例子中你得到:
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
顺便你可以看看 Implementation itself if you click on the source link in the hackage doc
就是这样
instance Functor ((->) r) where
fmap = (.)
我很难理解函数的函数结构。
我想我对 ghci 有所了解:
Prelude> :t (->)
(->) :: * -> * -> *
因此,如果输入一个类型,对其应用 (->) 将得到所需的类型 * -> *,这对于 Functor 定义是可以的。
但是我找不到我们可以写的原因:
Prelude> let test = fmap (+1) (+1)
Prelude> :t test
test :: Integer -> Integer
处理 (->) 时使用的仿函数实例是什么?它看起来像什么?
它有什么作用?我的意思是我不明白第一个 (+1) 对第二个函数 (+1)
的影响您的推理完全正确 - 现在您只需考虑这对您的仿函数实例意味着什么。
通常你的 functors 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
到函数 fmap g f :: r -> b
(->) r
的仿函数实例如下所示:
instance Functor ((->) r) where
fmap g f = \ r -> g (f r) -- = g . f
当你第一次看到它时有点奇怪,但它基本上只是函数组合(或者如果你喜欢 source-type 是常量并且你 fmap 应用你的函数的结果)
所以在这个例子中你得到:
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
顺便你可以看看 Implementation itself if you click on the source link in the hackage doc
就是这样
instance Functor ((->) r) where
fmap = (.)