Тип выводится из того, что уже известно о типах и о том, как выражения используются в определении.
Давайте начнем с верха,
rc v g i = g (v : i)
так rc :: a -> b -> c -> d
и мы должны увидеть, что можно узнать о a, b, c
и d
. С правой стороны появляется (v : i)
, поэтому с v :: a
мы видим, что i :: [a]
, c = [a]
. Затем g
применяется к v : i
, поэтому g :: [a] -> d
, в целом,
rc :: a -> ([a] -> d) -> [a] -> d
rn x = x
означает, что нет никаких ограничений на тип аргумента rn
, и его тип возврата такой же, rn :: a -> a
.
rh g = hd (g [])
Поскольку аргумент rh
g
применяется к пустому списку в RHS, он должен иметь тип [a] -> b
, возможно, дополнительная информация о a
или b
приведена ниже. Действительно, g []
является аргументом hd
на RHS, поэтому g [] :: [c]
и g :: [a] -> [c]
, следовательно,
rh :: ([a] -> [c]) -> c
Далее
f [] y = y
f (x:xs) y = f xs (rc x y)
Первый аргумент является списком, и если он пуст, результатом является второй аргумент, поэтому f :: [a] -> b -> b
следует из первого уравнения. Теперь во втором уравнении RHS второй аргумент f
равен rc x y
, следовательно, rc x y
должен иметь тот же тип, что и y
, мы назвали его b
. Но
rc :: a -> ([a] -> d) -> [a] -> d
, значит b = [a] -> d
. Следовательно
f :: [a] -> ([a] -> d) -> [a] -> d
Наконец
g [] y = y
g (x:xs) y = g xs (x:y)
из первого уравнения мы выводим g :: [a] -> b -> b
. Из второго мы выводим b = [a]
, так как мы берем голову первого аргумента g
и выводим его во второй, таким образом
g :: [a] -> [a] -> [a]