Количество аргументов и бессмысленных в Хаскеле

При множественном сопоставлении с образцом разное количество аргументов невозможно, даже при отсутствии смысла!

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

неправильно, потому что ветви имеют разные типы.

Конечно, это махание рукой, реальные вещи, происходящие за кулисами, более сложны

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