为什么明斯特编译器认为++中的模式匹配是非确定性的?

时间:2018-04-04 03:04:47

标签: compilation functional-programming logic-programming declarative-programming curry

我最近安装了明斯特咖喱编译器来替换我正在使用的速度慢得多的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 个答案:

答案 0 :(得分:1)

我对MCC没有任何肯定的知识,但PAKCS将功能模式转换为(高度)非确定性表达。当在IO中使用非确定性计算时,观察到的行为归结为MCC和PAKCS的不同行为。在PAKCS中,将评估非确定性计算,并且只有在表达式求值为多个结果时才会出现运行时错误。

也就是说,您可以在PAKCS中执行以下操作,而不会出现运行时错误。

REPL> putStrLn ("Hello" ? failed)
"Hello"

但是,以下计算将产生(相当晚)运行时错误。

REPL> putStrLn ("Hello" ? "Hello")
Hello
Hello
ERROR: non-determinism in I/O actions occurred!

我猜想MCC会针对非确定性计算做出不同的(并且更合理;))检查。

最后的一些广告:我通常使用KiCS2 - 您是否有使用MCC的具体原因?

编辑:如果您想更多地了解功能模式及其实现,您应该看一下下面的文章。

Declarative Programming with Function Patterns