Почему недетерминированная функция выбора в стандартной библиотеке Curry определена не напрямую, а с помощью вспомогательной функции с двумя аргументами?

Рассмотрим функцию choose в языке программирования Curry со спецификацией, которая « (select xs) недетерминированно выбирает один элемент из списка xs ".

Я бы реализовал это напрямую с помощью двух альтернативных недетерминированных правил:

choose :: [a] -> a
choose x:_ = x
choose _:xs = choose xs

Но в /usr/lib/curry-0.9.11/Success.curry из компилятора Muenster Curry ], он определяется с помощью вспомогательной функции:

choose (x:xs) = choosep x xs
  where choosep x [] = x
        choosep x (_:_) = x
        choosep _ (x:xs) = choosep x xs

Какие могут быть преимущества (если есть) определения из модуля, поставляемого компилятором? Полностью эквивалентны ли эти 2 определения (даже в некоторые сложные случаи с недетерминизмом и неопределенными значениями)? .. Является ли один из них более эффективным в некоторых случаях?

ДОБАВЛЕНО: Более глубокое рассмотрение

cthom06 (Спасибо!) правильно указал, что мое определение вызовет попадание в undefined значение в гораздо большем количестве случаев (потому что мы попытаемся вызвать эту функцию с аргументом пустого списка один раз для каждого нашего вызова «верхнего уровня» с изначально непустым аргументом списка). (Хм, а почему я не сразу заметил это соображение? ..) Это менее эффективно.

Но мне интересно: есть ли семантические различия? Может ли разница быть важной в некоторых сложных контекстах?

Мы видим, что разница между двумя определениями - в случае непустых списков - в основном сводится к различию между двумя потенциальными определениями для id :

мое определение похоже на определение id как:

id x = x
id _ = undefined

и их определение похоже на определение defig id обычным способом:

id x = x

(Итак, здесь упор делается на обратную прямоту.)

В каких контекстах это может быть важно?

15
задан imz -- Ivan Zakharyaschev 3 April 2011 в 23:35
поделиться