foldr的定义是(根据https://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.Base.html#local-6989586621679020249)
foldr :: (a -> b -> b) -> b -> [a] -> b
这意味着第一个参数的类型为(a -> b -> b)
,第二个参数b
,第三个[a]
并返回b
。
如果我们看一个例子:
foldr (-) 54 [10, 11]
-
是否接受相同类型的两个并返回相同类型?难道不是(a -> a -> a)
吗?
答案 0 :(得分:7)
该函数的签名为a -> b -> b
的事实的确不是 ,这意味着a
和b
应该是不同的类型。这意味着a
和b
可以是不同的类型。
例如,如果您使用(-) :: Num c => c -> c -> c
,则Haskell会得出结论:
foldr :: (a -> b -> b) -> (b -> ([a] -> b))
(-) Num c => c -> c -> c
----------------------------------------------------
a ~ c, b ~ c
因此,a
和b
和c
在这里是同一类型。 foldr (-)
的类型因此为:
foldr (-) :: Num c => c -> ([c] -> c)
因此, foldr (-)
采用多个类型c
,并返回将c
列表映射到c
的函数。
答案 1 :(得分:2)
我想用这个术语来解释这个主题:
f :: a -> b -> b
f x y = y
这是完全正确的,a
和b
可以不同,并且具有不同的类型,但是它并没有说它不可能是同一类型,所以:
v = f 'c' True
v :: Bool
在这里f :: Char -> Bool -> Bool
但您也可以执行以下操作:
v2 = f False True
v3 = f False False
v2 :: Bool
v3 :: Bool
此处f :: Bool -> Bool -> Bool
不同是当您希望这两个类型属于同一类型并限制它们时,例如:
sameTypeTuple :: a -> a -> (a,a)
sameTypeTuple x y = (x,y)
您将参数限制为相同类型:
v4 = sameTypeTuple 'a' 'b'
v4 :: (Char, Char)
但是
v5 = sameTypeTuple 'c' True
会给你
error:
• Couldn't match expected type ‘Char’ with actual type ‘Bool’
• In the second argument of ‘sameTypeTuple’, namely ‘True’
In the expression: sameTypeTuple 'c' True
In an equation for ‘it’: it = sameTypeTuple 'c' True
最后:
在foldr (-) 54 [10, 11]
中,您说a
和b
的类型为Num a0 => a0)
的类型a0
(类型为a0
,不是Num
,Num
是constrait,类型类)