我注意到(尽管有人告诉过我
(a->a)
和a->a
意思相同),但当我使用(a->a)
时会出现错误消息。那么,在类型之间使用括号时,我应该仅使用(a->a)
吗?(例如(5 + 3)
而不是5 + 3
)?我不确定何时需要使用它。(a->a)
和a->a
意思相同),但当我使用(a->a)
时会出现错误消息。那么,在类型之间使用括号时,我应该仅使用(a->a)
吗?(例如(5 + 3)
而不是5 + 3
)?我不确定何时需要使用它。(a -> a)
和 a -> a
在单独使用时是相同的
ff :: (a -> a) -- this compiles
ff = id
gg :: a -> a
gg = id
h :: a -> a -> Bool
h _ _ = True
i = h ff gg -- this compiles => ff & gg are of the same type.
但是当与更多类型组合时,结果会有所不同,例如:
a -> a -> b
(a -> a) -> b
这是因为->
是右结合的,所以a -> a -> b
实际上意味着a -> (a -> b)
(获取a
并返回一个函数),与(a -> a) -> b
(获取一个函数并返回b
)不同。
这就像(1+2)*3
不同于1+2*3
。
10 / 2 / 5
。这是否与(10 / 2) / 5
或10 / (2 / 5)
相同?如果您将/
解释为数学除法,则前者是正确的,而后者是错误的。因此,你看,你的问题的答案是“有差异,但只有在某些情况下”。a -> b -> c
与a -> (b -> c)
相同,并且绝对不同于(a -> b) -> c
。map :: (a -> b) -> [a] -> [b]
。这不同于a -> b -> [a] -> [b]
,因为(a -> b)
表示特定类型的函数:从类型a
到类型b
的函数。
iterate :: (a -> a) -> a -> [a]
则更有趣。该函数要求第一个参数中函数的输入和输出类型必须相同。这只有在编写高阶函数时才会有所区别。例如:
f :: a -> a -> b
是一个函数,它期望两个类型为a
的参数,并返回一个类型为b
的值,就像这样
f 2 2
f True True
但这个函数
f :: (a -> a) -> b
期望一个函数作为参数。只有在类型推断的唯一参数中,a -> a
和(a -> a)
才是相同的,就像这里一样。
f :: (a -> a)
-- Same type as
f :: a -> a
()
在类型转换中的规则与普通表达式基本相同。它就像是高一级的表达式。
它们是一样的。你能描述一下当你使用(a -> a)
时出现的错误吗?我在ghci-7.0.3上使用它没有问题:
Prelude> let f :: (a -> a); f = id
Prelude> f "foo"
"foo"
Prelude>
map :: (a -> b) -> [a] -> [b]
。如果没有括号,它会意味着其他的东西。