Возьмем это выражение (где оба p
должны иметь один и тот же тип, потому что лямбда-переменная не может иметь два типа одновременно, если вы явно не указываете полиморфный тип):
p 1 p
Какой тип p
в этом контексте? Допустим, 1
- это Int
для простоты. Начнем с простой попытки:
(p :: Int -> ? -> Int) 1 p
Итак, что за знак вопроса? Ну, это должен быть тип p
, потому что это аргумент, который вы приводите. Итак:
(p :: Int -> (Int -> ? -> Int) -> Int) 1 p
Опять та же проблема, то же решение:
(p :: Int -> (Int -> (Int -> ? -> Int) -> Int) -> Int) 1 p
Теперь вы понимаете, почему у нас проблема с бесконечными типами: хотя нам не нужно , чтобы узнать тип второго аргумента p
; Поскольку система типов Haskell является строгой (иначе говоря, не ленивой), ей все равно нужно выяснить тип, и она застревает с этим бесконечным типом.
Этот код успешно выполняется:
(\x y -> 1) 1 p
... потому что функция слева может иметь тип , отличный от p
, потому что это разные функции, поэтому мы не сталкиваемся с той же проблемой при объединении типов:
((\ x y -> 1) :: a -> b -> Int) 1 (p :: c -> d -> Int)