Количество аргументов и бессмысленных в Хаскеле
При множественном сопоставлении с образцом разное количество аргументов невозможно, даже при отсутствии смысла!
foo True b = b + 2
foo _ = id
не работает например. Но
foo True = (+2)
foo _ = id
делает. Иногда мы можем использовать бессмысленное использование только в одной части функции, так что...
Зачем? Это слишком сложно для GHC?:'(
2 ответа
Зачем? Это слишком сложно для GHC?
Нет Это не так уж сложно для GHC. На самом деле, это вина отчета Хаскелла.
См.: Haskell Report 2010> Объявления и привязки> Привязки функций
Привязка функции связывает переменную со значением функции. Общая форма привязки функции для переменной x:
x p11 … p1k match1
...
x pn1 … pnk matchn[... бла-бла...]
Перевод: Форма общего связывания для функций семантически эквивалентна уравнению (то есть простое связывание с образцом):
x = \ x1 … xk -> случай (x1,…, xk) из
(p11, …, p1k) match1
...
(pn1, …, pnk) matchn
где хя новые идентификаторы.
(акцент мой)
Хотя определения функций семантически эквивалентны лямбда-выражению и регистру, они не обязательно компилируются таким образом, как предлагает Михай.
Дело в том, что в отчете Haskell определяются объявления функций, так что они должны иметь одинаковое количество входов в левой части уравнения. Это становится ясно из того факта, что k
остается одинаковым как в 1-й, так и в n-й строках объявления функций (и, косвенно, все промежуточные строки). Это причина ограничения; это не имеет ничего общего с деталями реализации GHC.
ТЛ; др
Выбор не позволять это просто вопрос стиля. - augustss
Каждое функциональное уравнение должно иметь одинаковое количество аргументов. Вот почему ваш первый пример терпит неудачу.
Чтобы исправить это, используйте
foo True b = b + 2
foo _ x = id x
Как видите, оба уравнения имеют одинаковое количество аргументов.
Несколько уравнений, включающих сопоставление с образцом, переводятся в выражения случая. В твоем случае foo
переводится примерно как
foo a b = case a of
True -> b + 2
_ -> id x
Обе (все) ветви case
должен иметь тот же тип, таким образом, вы первый пример, который будет переведен как
foo a b = case a of
True -> b + 2
_ -> id
неправильно, потому что ветви имеют разные типы.
Конечно, это махание рукой, реальные вещи, происходящие за кулисами, более сложны