考虑Curry 编程语言choose
中的一个函数,其规范是“非确定性地从列表中选择一个元素”。(choose xs)
xs
我将通过两个替代的非确定性规则直接实现它:
choose :: [a] -> a
choose x:_ = x
choose _:xs = choose xs
但是在Muenster Curry Compiler的 /usr/lib/curry-0.9.11/Success.curry 中,它是使用辅助函数定义的:
choose (x:xs) = choosep x xs
where choosep x [] = x
choosep x (_:_) = x
choosep _ (x:xs) = choosep x xs
编译器提供的模块的定义有什么优点(如果有的话)?这两个定义是否完全等效(即使在一些具有不确定性和未定义值的棘手情况下)?..在某些情况下其中一个更有效吗?
补充:更深层次的考虑
cthom06(谢谢!)已正确指出我的定义会导致在更多情况下达到未定义的值(因为我们会尝试在每次“顶级”调用时使用空列表参数调用此函数一次非空列表参数)。(嗯,为什么我没有马上注意到这个考虑?..)那效率较低。
但我想知道:有任何语义差异吗?在某些棘手的情况下,差异可能很重要吗?
我们看到两个定义之间的差异——在非空列表的情况下——基本上归结为两个潜在定义之间的差异id
:
我的定义就像定义id
为:
id x = x
id _ = undefined
他们的定义就像定义id
正常的方式:
id x = x
(因此,这里的直截了当。)
在哪些情况下它可能很重要?