Ошибка типа Миранда

Может кто-нибудь сказать мне, где идет не так?

b f x = f x (f x)

Я понимаю так: потому что f слева принимает один аргумент, а с правой стороны - два аргумента?

Есть более подробные объяснения?

2 ответа

Давайте попробуем построить этот тип:

b :: ... ?

У нас есть как минимум два аргумента, поэтому давайте изменим b соответственно:

b :: a -> c -> d

Правая сторона b предполагает, что f это функция. Давайте сначала коснемся только первого аргумента:

f :: c -> e

До сих пор все складывалось довольно неплохо: первый аргумент списка имеет тот же тип, что и второй аргумент b. Давайте продолжим на правой стороне.

f x (f x)

Если мы возьмем f x _, мы должны предположить, что e является e :: k -> l мы принимаем другой аргумент. Теперь у нас есть

f :: c -> k -> l

Теперь посмотрим на тип f Второй аргумент Это тип должен быть одним из f x:

f x :: k -> l

Так k = k -> l, Это бесконечный тип, который мы также можем увидеть, посмотрев на сообщение об ошибке ghci:

Prelude> let bfx = fx (fx) : 2: 18: Происходит проверка: невозможно создать бесконечный тип: t1 = t1 -> t0 В возвращаемом типе вызова `f'Вероятная причина: `f' применяется к слишком немногим аргументам Во втором аргументе `f', а именно`(f x)' В выражении: f x (f x) 

Проверка типов сдается, поскольку бесконечный тип не может быть им построен. В конце концов, это происходит, так как вы подаете заявку f на другое количество аргументов.

Компилятор пытается определить тип f, Сначала он видит, что f принимает аргумент x и еще один аргумент (f x), который на данный момент мы подставим как y, Поэтому, когда компилятор видит что-то вроде f x yэто означает, что f имеет тип a -> b -> c, с x :: a, y :: b, а также f x y :: c, Затем он проверяет y ближе, видя, что его тип более конкретно b -> c, так как он уже знает f должен иметь второй аргумент. Так что теперь можно определить, что b ~ b -> c, И это где он должен остановиться, как можно b также b -> c? Если он продолжал заменять b ~ b -> c, он будет иметь бесконечную рекурсию, пытаясь выяснить, какой тип b является! Это, очевидно, не может работать, поэтому он выдает ошибку компиляции, говоря, что он не может создать бесконечный тип b = b -> c (примечание: в сообщении об ошибке могут использоваться имена, отличные от b или же c). Сообщение об ошибке, которое я получаю, на самом деле очень полезно:

Occurs check: cannot construct the infinite type: t1 = t1 -> t0
In the return type of a call of `f'
Probable cause: `f' is applied to too few arguments
In the second argument of `f', namely `(f x)'
In the expression: f x (f x)

Это говорит вам, где именно проблема, а именно (f x)"и дает вам вероятную причину"f применяется к слишком немногим аргументам ", говоря, что" не может создать бесконечный тип t1 = t1 -> t0".

Другие вопросы по тегам