Почему компилятор Münster считает, что соответствие шаблону в ++ недетерминировано?

Недавно я установил компилятор Münster Curry, чтобы заменить гораздо более медленный PAKCS, который я использовал. Первое, что я хотел проверить, это то, могу ли я использовать некоторые функции сопоставления шаблонов из PAKCS, потому что я знаю, что некоторые реализации (на ум приходит Sloth) не поддерживают все сопоставления шаблонов, которые допускает 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 обычно означает, что ввод-вывод зависит от недетерминированного поведения. Это заставляет меня подозревать, что MCC считает мою функцию f недетерминированной. Однако, насколько мне известно, f полностью детерминирован.

Что делает MCC, из-за чего он считает мою функцию недетерминированной?

Мне не нужно знать, как исправить программу, это очень просто, работает следующее:

import IO

f (a : b @ (_:_)) = a : f b
f [a] = []

main = print $ f $ "Hello, World!"

Мне интересно понять, что здесь делает компилятор, что приводит к ошибке, и чем это отличается от того, что делает PAKCS при компиляции кода.


person Éamonn Olive    schedule 04.04.2018    source источник


Ответы (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 -- есть ли конкретная причина, по которой вы используете Центр клиентов?

Редактировать: если вы хотите больше узнать о функциональных шаблонах и их реализации, вам, вероятно, следует взглянуть на следующую статью.

Декларативное программирование с использованием шаблонов функций

person ichistmeinname    schedule 06.04.2018
comment
Спасибо за ответ! Это помогает немного прояснить ситуацию. Что касается работы с MCC, я хотел использовать KiCS2, но у меня были некоторые проблемы с его компиляцией, поэтому я решил попробовать вместо него MCC. - person Éamonn Olive; 07.04.2018
comment
Если вас больше интересует, почему определения, использующие шаблоны функций, недетерминированы, я добавил статью, в которой объясняется реализация PAKCS. - person ichistmeinname; 10.04.2018
comment
Что касается проблем, которые у вас были с KiCS2: не стесняйтесь обращаться ко мне по этому поводу; ) - person ichistmeinname; 11.04.2018