FMAP的函子类型是:
fmap :: Functor f => (a -> b) -> f a -> f b
它看起来像,第一应用功能(一 - > b)至FA的参数来创建b型的结果,然后应用F到它,并且结果是FB
使用也许例如:
fmap show (Just 1)
result is : Just "1"
同样的话:
Just (show 1)
但是,当( - >)用作函子(在Control.Monad.Instances)
import Control.Monad.Instances
(fmap show Just) 1
result is : "Just 1"
也就是说,只要是申请,然后再应用展示。 在另一个例子中,结果是相同的:
fmap (*3) (+100) 1
result is 303
为什么不* 3,再+100?
FMAP的函子类型是:
fmap :: Functor f => (a -> b) -> fa -> fb
它看起来像,第一应用功能(一 - > b)至FA的参数来创建b型的结果,然后应用F到它,并且结果是FB
这是类型fmap
,但你的是什么类型的意思解释是错误的。
你似乎认为fa
有一个参数,而该参数的类型为a
。
考虑xs :: [a]
:
- 或许
xs = []
- 或许
xs = [x1]
- 或许
xs = [x1, x2]
- ...
类型 fa
是一个算符f
使用单一类型的参数a
。 但是类型的值 fa
不一定采取的形式F x
你可以从上面的第一和第三种情况看。
现在考虑fmap f xs
:
- 也许
fmap f xs = []
。 - 也许
fmap f xs = [f x1]
。 - 也许
fmap f xs = [f x1, f x2]
。 - ...
我们不一定适用f
所有(第一种情况)! 或者我们可以申请一次以上(第三种情况)。
我们做的是替换型的东西a
,有型的东西b
。 但是,我们离开了较大的结构不变---没有新元素的加入,没有元素去掉,它们的顺序保持不变。
现在,让我们想想仿函数(c ->)
(请注意,一个仿函数只需要一种类型的参数,所以输入到(->)
被固定)
做了c -> a
甚至包含a
? 它可能不包含任何a
s的一切,但它能够以某种神奇的一个凭空的时候,我们给它一个c
。 但是从结果fmap
具有类型c -> b
:我们只需要提供一个b
出来的,当我们提出了一个c
。
所以我们可以说fmap fx = \y -> f (xy)
在这种情况下,我们将f
需求---我们每次返回的功能被应用时, f
被应用为好。
该fmap
例如(->) r
(即函数)是从字面上只是组合物。 从源本身 :
instance Functor ((->) r) where
fmap = (.)
所以,在你的榜样,我们只需更换fmap
用(.)
并做一些转换
fmap (*3) (+100) 1 =>
(.) (*3) (+100) 1 =>
(*3) . (+100) $ 1 => -- put (.) infix
(*3) (1 + 100) => -- apply (+100)
(1 + 100) * 3 -- apply (*3)
也就是说, fmap
对它们的功能组成从右到左(完全一样(.)
这是明智的,因为它是(.)
看看它的另一种方式(!为(双)确认),我们可以使用类型签名:
-- general fmap
fmap :: Functor f => (a -> b) -> f a -> f b
-- specialised to the function functor (I've removed the last pair of brackets)
fmap :: (a -> b) -> (r -> a) -> r -> b
类型,使得第一值r
第三个参数)需要被转化成类型的值a
(由r -> a
功能),使a -> b
函数可以将其转换类型的值b
(结果)。
它需要被定义的方式,使各类工作了。 正如你所指出的类型, fmap
是:
fmap :: Functor f => (a -> b) -> f a -> f b
让我们考虑的情况下,当函子f
是((->) c)
( 注:我们会真正喜欢写为(c ->)
即从功能c
,但哈斯克尔不允许我们这样做。)
然后fa
实际上是((->) ca)
其等同于(c -> a)
,并且类似地对于fb
,因此我们有:
fmap :: (a -> b) -> (c -> a) -> (c -> b)
也就是说,我们需要采取两个功能:
并构建新功能
但是,只有一个做到这一点的方法:你必须申请g
率先拿到类型的东西a
,然后应用f
拿到类型的东西b
,这意味着你必须定义
instance Functor ((->) c) where
fmap f g = \x -> f (g x)
或者,更简洁,
instance Functor ((->) c) where
fmap = (.)
fmap
为(->)
被定义像fmap = (.)
所以, (fmap fg) x
是(f . g) x
是f (gx)
你的情况(*3) ((+100) 1)
它等于3 * (100 + 1)
这导致303
。
为了形成一个功能类型,需要2个参数( - >),即单输入参数类型和返回类型。
仿函数只能取1个类型参数,所以你必须明确的输入参数类型(因为它是从第一个左到右),这使得该函数的返回类型为仿函数的类型参数。
所以对于功能(仿函数)A-> B,你需要给FMAP FF类型的函数B-> XXX比A-> XXX工作,这意味着功能FF后,才能A-应用> B以外是适用。