Что означает скобки в сигнатурах типа Haskell?
возьмите подпись типа fmap
(the Functor
способ) в качестве примера:
(a -> b) -> f a -> f b
чем это отличается от подписи следующего типа?
a -> b -> f a -> f b
есть ли разница между этими двумя сигнатурами типов?
3 ответов
Да, есть разница, потому что на ->
конструктор типа право-ассоциативной. Другими словами,
a -> b -> f a -> f b
эквивалентно
a -> (b -> (f a -> f b))
этот тип сигнатуры обозначает функцию, которая принимает параметр типа a
и возвращает функцию, которая сама принимает параметр типа b
и возвращает функцию, которая сама принимает параметр типа f a
и возвращает значение типа f b
.
С другой стороны,
(a -> b) -> f a -> f b
обозначает функцию, которая принимает параметр типа a -> b
(т. е. функция, которая принимает параметр типа a
и возвращает значение типа b
) и возвращает функцию, которая сама принимает параметр типа f a
и возвращает значение типа f b
.
вот пример, который иллюстрирует разницу между этими двумя подписями типа:
f :: (Int -> Bool) -> [Int] -> [Bool]
f = map
g :: Int -> Bool -> [Int] -> [Bool]
g n b = map (\n' -> (n' == n) == b)
λ> let ns = [42, 13, 42, 17]
λ> f (== 42) ns
[True,False,True,False]
λ> g 42 True ns
[True,False,True,False]
λ> g 42 False ns
[False,True,False,True]
да
(a -> b) -> ...
означает " заданная функция, которая принимает a в b ...". А этот
a -> b -> ...
означает " учитывая некоторые a и некоторые b..."
Да (a -> b)
означает один аргумент, который является функцией с подписью a -> b
, тогда как a -> b -> ...
значит два аргумента.