为什么Curry的std lib中的非确定性选择函数没有直接定义,而是使用辅助2参数函数?

考虑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
编译器提供的模块定义的优点(如果有的话)是什么? 2个定义是否完全相同(即使在一些非确定性和未定义值的棘手情况下)?在某些情况下,其中一个更有效吗? 增加:更深入的考虑 cthom06(谢谢!)已经正确地指出我的定义会导致在更多情况下达到未定义的值(因为我们会尝试使用一个空列表参数调用此函数,每次我们的“顶级”调用一次非空列表参数)。 (嗯,为什么我没有立刻注意到这个考虑因素?..)效率较低。 但我想知道:有任何语义差异吗?可能在一些棘手的情况下,差异是否重要? 我们看到两个定义之间的区别 - 在非空列表的情况下 - 基本上归结为
id
的两个潜在定义之间的差异: 我的定义就像定义
id
id x = x
id _ = undefined
他们的定义就像definig
id
正常的方式:
id x = x
(所以,这里的直截了当还原。) 在哪些情况下它很重要?     
已邀请:
我相信没有语义差异,但是具有辅助函数的那个​​更有效,特别是在具有一个元素的列表的常见情况下(在某些编程风格中)。在这种情况下,避免了一个选择点,你的版本需要设置为以[]递归调用,然后绑定失败。 一个更聪明的优化器可能会解决这个问题,但处理各种类似的情况可能很有挑战性 - 编译器需要尝试为数据类型中的每个可能的构造函数专门化应用程序,删除那些始终发生故障的应用程序,以及当只剩下一种可能性时删除选择点。     

要回复问题请先登录注册