tryout
принимает любую функцию в качестве аргумента и возвращает целое число.Поскольку у вас нет никакого значения для вызова функции, tryout
ничего не может сделать, кроме как игнорировать ее и вернуть некоторое целое число.(Существует одна общая реализация tryout
для каждого значения типа Int
.)
tryout :: (a -> b) -> Int
tryout _ = 4
-- tryout (+) == 4; (+) :: Num x => x -> x -> x, where a ~ x and b ~ x -> x
-- tryout return == 4; return :: Monad m => x -> m x, where a ~ x and b ~ m a
-- tryout length == 4; length :: Foldable t => t x -> Int, where a ~ t x and b ~ Int
-- etc
Если tryout
также принял дополнительный аргумент для типа a
,Вы могли бы по крайней мере применить функцию, чтобы получить значение типа b
, но вы все равно ничего не могли с этим поделать, поскольку tryout
должен возвращать Int
.
tryout :: (a -> b) -> a -> Int
tryout _ _ = 4
-- tryout length "foo" == 4; a ~ String, b ~ Int
Теперь представьте, что помимо функции типа a -> b
, значения типа a
, у вас также есть аргумент типа b -> Int
. Теперь мы, наконец, можем сделать что-то нетривиальное (хотя все еще простое).
tryout :: (a -> b) -> a -> (b -> Int) -> Int
tryout f x g = g (f x)
Мы применяем f
к x
, чтобы получить значение типа b
, затемпередайте это g
, чтобы получить Int
, который мы можем вернуть.Это не определение only , которое проверяет тип;мы все еще можем игнорировать f
, x
и g
и возвращать фиксированный Int
, как в предыдущих примерах.