Functor中的fmap类型是:
fmap :: Functor f => (a -> b) -> f a -> f b
Run Code Online (Sandbox Code Playgroud)
看起来,首先将函数(a - > b)应用于fa的参数以创建类型b的结果,然后对其应用f,结果为fb
使用Maybe a例如:
fmap show (Just 1)
result is : Just "1"
Run Code Online (Sandbox Code Playgroud)
同说:
Just (show 1)
Run Code Online (Sandbox Code Playgroud)
但是当( - >)用作Functor时(在Control.Monad.Instances中)
import Control.Monad.Instances
(fmap show Just) 1
result is : "Just 1"
Run Code Online (Sandbox Code Playgroud)
也就是说,Just首先应用,然后显示应用.在另一个例子中,结果是相同的:
fmap (*3) (+100) 1
result is 303
Run Code Online (Sandbox Code Playgroud)
为什么不*3先,然后+100?
huo*_*uon 33
(即函数)的fmap实例(->) r实际上只是组合.从源本身:
instance Functor ((->) r) where
fmap = (.)
Run Code Online (Sandbox Code Playgroud)
所以,在你的榜样,我们就可以代替fmap用(.),并做一些转换
fmap (*3) (+100) 1 =>
(.) (*3) (+100) 1 =>
(*3) . (+100) $ 1 => -- put (.) infix
(*3) (1 + 100) => -- apply (+100)
(1 + 100) * 3 -- apply (*3)
Run Code Online (Sandbox Code Playgroud)
也就是说,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
Run Code Online (Sandbox Code Playgroud)
所以首先r需要将type (第三个参数)的值转换为类型的值a(通过r -> a函数),以便a -> b函数可以将其转换为类型的值b(结果).
dav*_*420 26
Functor中的fmap类型是:
Run Code Online (Sandbox Code Playgroud)fmap :: Functor f => (a -> b) -> f a -> f b看起来,首先将函数(a - > b)应用于fa的参数以创建类型b的结果,然后对其应用f,结果为fb
这是类型fmap,但你对这种类型的解释是错误的.
您似乎假设f a有一个参数,并且该参数具有类型a.
考虑xs :: [a]:
xs = [].xs = [x1].xs = [x1, x2].该类型 f a是f具有单个类型参数的仿函数a.但是,从上面的第一和第三种情况可以看出,类型的值f a不一定采用这种形式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?它可能根本不包含任何as,但是当我们给它一个时,它可以以某种方式用空气来魔术c.但是从结果fmap具有类型c -> b:我们只需要提供b出的,当我们提出了一个c.
所以我们可以说fmap f x = \y -> f (x y).
在这种情况下,我们f按需应用---每当我们返回的函数被应用时,f也会应用.
Chr*_*lor 17
它需要被定义的方式,使各类工作了.正如您所指出的那样,类型fmap是:
fmap :: Functor f => (a -> b) -> f a -> f b
Run Code Online (Sandbox Code Playgroud)
让我们考虑仿函数的f情况((->) c)
(注意:我们实际上喜欢将其写为(c ->),即函数c,但Haskell不允许我们这样做.)
那么f a实际上((->) c a),这相当于(c -> a),同样f b如此,所以我们有:
fmap :: (a -> b) -> (c -> a) -> (c -> b)
Run Code Online (Sandbox Code Playgroud)
即我们需要采取两个功能:
f :: a -> bg :: c -> a并构建一个新的功能
h :: c -> b但是只有一种方法可以做到这一点:你必须首先申请g获得类型的东西a,然后申请f获得类型的东西b,这意味着你必须定义
instance Functor ((->) c) where
fmap f g = \x -> f (g x)
Run Code Online (Sandbox Code Playgroud)
或者,更简洁,
instance Functor ((->) c) where
fmap = (.)
Run Code Online (Sandbox Code Playgroud)
fmapfor (->)定义为fmap = (.).所以,(fmap f g) x 是(f . g) x的f (g x).在你的情况下(*3) ((+100) 1),等于3 * (100 + 1)导致的结果303.