[英]Do Not Understand fmap of Function and Value in Haskell
我对此表达式的结果感到困惑:
fmap (*) 3
产生类型:
fmap (*) 3 :: (Functor f, Num a, Num (f a)) => f (a -> a)
我期望的是结果将与这样做相同:
(*) 3
产生一个1-参数的函数:
Prelude> (*) 3 $ 10
30
我期望fmap
将3
应用于(*)
产生(*3)
,但是以下产生错误:
Prelude> (fmap (*) 3) 10
<interactive>:201:1:
Non type-variable argument in the constraint: Num (a -> a)
(Use FlexibleContexts to permit this)
When checking that `it' has the inferred type
it :: forall a a1. (Num a, Num a1, Num (a1 -> a)) => a -> a
(fmap (*) 3)
预期的结果是什么类型的参数?
关键在这里:
fmap (*) 3 :: (Functor f, Num a, Num (f a)) => f (a -> a)
^^^^^^^^^
在Haskell中,数字文字被重载,因此3
可以具有任何类型b
,只要b
具有Num
实例即可。
编译器进行以下分析:
b
与约束Num b
fmap
类型为Functor f => (a -> c) -> fa -> fc
fmap
Functor f => (a -> c) -> fa -> fc
fmap
Functor f => (a -> c) -> fa -> fc
*
类型a -> c
fa
a -> c
,3的类型为fa
*
具有类型Num a => a -> a -> a
so c
= Num a
a -> a
,并且a
具有约束Num a
b
=(1)和(2)中的fa
收集所有约束和对等条件:
fmap (*) 3 :: ( Functor f, -- by (2)
Num a, -- by (4)
Num (f a) -- by (1) and (5)
) => f ( a -> a ) -- by (2) and c = a -> a
更新:
您要求一个示例,其中fmap (*) 3
有意义。 这里有问题的是(*)
具有arity 2,并且fmap
通常与单个参数(arity 1)一起使用。 例如:
fmap (+1) (Just 3) = Just 4
fmap (+1) Nothing = Nothing
fmap (*6) [1,2,3] = [6,12,18]
fmap words getLine = do x <- getLine; return (words x)
注意: (+1)
只是“加1”函数,例如\\x -> x+1
,而(*6)
只是乘以6的函数,例如\\x -> x*6
。
因此,映射(*) :: Int -> Int -> Int
Int- (*) :: Int -> Int -> Int
Int- (*) :: Int -> Int -> Int
有点不寻常。 当然,我们可以将(*)
的类型解释为Int -> (Int -> Int)
,从而得到奇数1,但是处理函数的函子将进入我们通常不处理的抽象级别用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.