В Haskell, почему неистоирующие шаблоны не являются ошибками времени с компиляцией?

StackOverflow https://stackoverflow.com/questions/3804484

Вопрос

Это наблюдение Почему я получаю «неистовые модели в функции ...», когда я вызываю свою функцию подстроки Haskell?

Я понимаю, что используя -Wall, GHC может предупредить против неистовых узоров. Мне интересно, в чем причина не делает его ошибкой времени компиляции по умолчанию, учитывая, что всегда возможно четко определить частичную функцию:

f :: [a] -> [b] -> Int
f [] _  = error "undefined for empty array"
f _ []  = error "undefined for empty array"
f (_:xs) (_:ys) = length xs + length ys

Вопрос не специфичен GHC.

Это потому, что ...

  • Никто не хотел принудить компилятор Haskell для выполнения такого рода анализа?
  • Неиспользуемый поиск шаблона может найти некоторые, но не все случаи?
  • Частично определенные функции считаются законными и часто используются достаточно, чтобы не наложить вид конструкции, показанной выше? Если это так, вы можете объяснить мне, почему неиспользующиеся узоры полезны / законно?
Это было полезно?

Решение

Есть случаи, когда вы не против, что матч шаблона не исчерпывающий. Например, хотя это не может быть оптимальной реализацией, я не думаю, что это поможет, если бы не скомпилировалась:

fac 0 = 1
fac n | n > 0 = n * fac (n-1)

То, что это не исчерпывающее (негативные числа не соответствуют любому случаю), не имеет значения для типичного использования факториальной функции.

Также, как правило, не может быть возможно решение для компилятора, если шаблон матча является исчерпывающим:

mod2 :: Integer -> Integer
mod2 n | even n = 0
mod2 n | odd n  = 1

Здесь все случаи должны быть покрыты, но компилятор, вероятно, не может его обнаружить. Поскольку охранники могут быть произвольно сложным, компилятор не всегда может решить, являются ли узоры исчерпывающими. Конечно, этот пример лучше будет написано с otherwise, но я думаю, что он должен также компилировать в своей текущей форме.

Другие советы

Вы можете использовать -Werror Чтобы включить предупреждения в ошибки. Я не знаю, можете ли вы повернуть только неистонарующие шаблоны предупреждения об ошибках, извините!

Что касается третьей части вашего вопроса:

Я иногда пишу ряд функций, которые, как правило, тесно сотрудничают и имеют свойства, которые вы не можете легко выразить в Haskell. По крайней мере, некоторые из этих функций, как правило, не исчерпывающие узоры, обычно «потребителей». Это подходит, например, в функциях, которые являются «сортирующими» надписями друг друга.

Пример игрушки:

duplicate :: [a] -> [a]
duplicate [] = []
duplicate (x:xs) = x : x : (duplicate xs)

removeDuplicates :: Eq a => [a] -> [a]
removeDuplicates [] = []
removeDuplicates (x:y:xs) | x == y = x : removeDuplicates xs

Теперь довольно легко увидеть, что removeDuplicates (duplicate as) равно as (всякий раз, когда тип элемента находится в Eq), но в целом duplicate (removeDuplicates bs) Повысьте, потому что есть нечетное количество элементов или 2 последовательных элемента различаются. Если это не хватает, это потому что bs был произведен (или мог быть произведен) duplicate в первую очередь!.

Таким образом, у нас есть следующие законы (не допустимые Haskell):

removeDuplicates . duplicate == id
duplicate . removeDuplicates == id (for values in the range of duplicate)

Теперь, если вы хотите предотвратить отсутствие исчерпывающих шаблонов, вы можете сделать removeDuplicates вернуть Maybe [a], или добавьте сообщения об ошибках для отсутствующих случаев. Вы могли бы даже сделать что-то вдоль линий

newtype DuplicatedList a = DuplicatedList [a]

duplicate :: [a] -> DuplicatedList a
removeDuplicates :: Eq a => DuplicatedList a -> [a]
-- implementations omitted

Все это необходимо, потому что вы не можете легко выразить «быть список четных длин, причем пары последовательных элементов равны» в системе типа Haskell (если вы не олег :)

Но если вы не экспортируете removeDuplicates Я думаю, что это совершенно в порядке, чтобы использовать неистонарующиеся узоры здесь. Как только вы экспортируете его, вы потеряете контроль над входами и придется иметь дело с недостающими случаями!

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top