Почему компилятор Мюнстера считает, что сопоставление с образцом в ++ недетерминировано?
Недавно я установил Münster Curry Compiler, чтобы заменить гораздо более медленную PAKCS, которую я использовал. Первым делом я хотел проверить, могу ли я использовать некоторые функции сопоставления с образцом из PAKCS, потому что я знаю, что некоторые реализации (которые приходят на ум, - Ленивец) не поддерживают все сопоставления с образцами, которые допускает PAKCS. Поэтому я написал следующую программу:
import IO
f (a ++ [b]) = a
main = print $ f $ "Hello, World!"
Это работает в PAKCS и печатает Hello, World
как и ожидалось, но при компиляции с MCC я получаю ошибку:
Error: cannot duplicate the world
Насколько я понимаю, это означает, что MCC не может соответствовать шаблону ++
, но я не понимаю, почему MCC выбирает эту ошибку. cannot duplicate the world
обычно означает, что IO зависит от недетерминированного поведения. Это заставляет меня подозревать, что MCC считает, что моя функция f
является недетерминированным. Однако, насколько мне известно f
является полностью детерминированным.
Что делает MCC, что заставляет его думать, что моя функция недетерминирована?
Мне не нужно знать, как исправить программу, это действительно легко, работает следующее:
import IO
f (a : b @ (_:_)) = a : f b
f [a] = []
main = print $ f $ "Hello, World!"
Мне интересно понять, что делает здесь компилятор, что приводит к его ошибке и как это отличается от того, что делает PAKCS при компиляции кода.
1 ответ
Я ничего точно не знаю в отношении MCC, но PAKCS переводит функциональные паттерны в (сильно) недетерминированное выражение. Наблюдаемое поведение сводится к разному поведению MCC и PAKCS при использовании недетерминированных вычислений в IO. В PAKCS выполняется недетерминированное вычисление, и ошибка времени выполнения возникает, только если выражение вычисляет более одного результата.
То есть, вы можете сделать следующее в PAKCS, не получая ошибку времени выполнения.
REPL> putStrLn ("Hello" ? failed)
"Hello"
Однако следующие вычисления приведут к (довольно поздней) ошибке во время выполнения.
REPL> putStrLn ("Hello" ? "Hello")
Hello
Hello
ERROR: non-determinism in I/O actions occurred!
Я бы предположил, что MCC делает другую (и более разумную;)) проверку в отношении недетерминированных вычислений.
Немного рекламы в конце: я обычно работаю с KiCS2 - есть ли конкретная причина, по которой вы используете MCC?
Изменить: Если вам нравится больше о функциональных шаблонах и их реализации, вам, вероятно, стоит взглянуть на следующую статью.
Декларативное программирование с использованием шаблонов функций