Неопровержимые / ленивые упражнения в хаскельском викибуке
На полпути здесь...
https://en.wikibooks.org/wiki/Haskell/Laziness
... это упражнение, спрашивающее о последствиях изменений в альтернативной реализации head
функция, которая использует неопровержимые образцы. Это дает определение head'
следующим образом, отмечая, что он всегда вернется undefined
из-за неопровержимого соответствия первого уравнения:
head' :: [a] -> a
head' ~[] = undefined
head' ~(x:xs) = x
Затем он спрашивает:
- Почему бы не изменить порядок уравнений на
head'
помочь здесь? - Если первое уравнение будет изменено для использования обычного опровержимого шаблона, будет ли поведение
head'
все еще отличаться отhead
? Если так, то как?
В GHC 7.8.4 кажется, что изменение порядка "помогает", по крайней мере, до такой степени, что эта функция ведет себя как обычная частичная версия head
, хотя с другим исключением в случае пустого списка. Мне кажется, что ответом на второй вопрос будет "нет", но, учитывая дополнение "если да, как", мне кажется, что и здесь что-то не хватает. Кто-нибудь может просветить меня? Ссылка на решения на странице, к сожалению, не охватывает это упражнение.
1 ответ
Я не уверен, что викибук означает "помощь". Вы правы в том, что изменение порядка приведет к тому, что он будет вести себя в основном как обычный head
, Точно так же вы правы в том, что если сделать первый шаблон проверяемым, то он будет вести себя как head
, Я собираюсь сказать, что эти вопросы запутаны; они определенно сбивают с толку.
Мы можем проверить эти ответы расчетом (включая расчет с GHC):
head [] = ⊥
head (x:xs) = x
head ⊥ = ⊥
head' [] = ⊥
head' (x:xs) = ⊥
head' ⊥ = ⊥
head1 [] = ⊥
head1 (x:xs) = x
head1 ⊥ = ⊥
head2 [] = ⊥
head2 (x:xs) = x
head2 ⊥ = ⊥
head
стандартная версия библиотеки head'
это версия из викибука. head1
версия с замененными пунктами. head2
версия с первым шаблоном, представляющим собой опровержимое совпадение с []
, Read читается как "снизу" и представляет собой не заканчивающееся или исключительное вычисление, т.е. undefined
,
Я ожидал бы таких примеров, как следующие, где есть тонкие, но существенные различия между опровержимыми и неопровержимыми образцами:
konst ~() = ()
konst' () = ()
partialId ~(x:xs) = x:xs
partialId' (x:xs) = x:xs