Краткий ответ : код не является рекурсивным .
Не могли бы вы предоставить нерекурсивную рекурсивную версию сортировки выбора?
Код , а не хвостовая рекурсия.Это " хвостовая рекурсия по модулю минусов " [wiki] , но не хвостовая рекурсия.
В Haskell wiki показано, как узнать,функция хвостовой рекурсии:
Вот формальное определение "хвостовой рекурсии".«f
встречается в t
» означает, что f
является свободной переменной t
.
Когда функция определена (в let или на верхнем уровне) как:
f = t
, где f
- это имя, а t
- лямбда-термин, f
- хвостовая рекурсивность, если f
встречается в хвосте рекурсивно в t
.f
встречается рекурсивно в t
, если * f
встречается в t
и выполняется любое из следующих условий:
t
является переменным; t
равно \var -> t0
и f встречается в хвосте рекурсивно в t0
; t
равно t0 t1
, а f встречается в хвосте рекурсивно в t0
и не встречается в t1
; t
равно let bs in t0
и f
встречается рекурсивно в t0
и для каждого связующего var = t1
в bs
, f
не встречается в t1
; t
- это case t0 of bs
, а f
не встречается в t0
и для каждой ветви b
в bs
, f
не встречается или происходит рекурсивно в b
; - когда мы говорим "встречаются в
b
", b
имеет форму D vars -> t1
(где D
- некоторый конструктор данных, а vars
- последовательность имен), мы думаем олямбда-абстракция \vars -> t1
вместо b
.
Выражение t
равно \xs -> let x = minimum xs in x : ssort (delete x xs)
, поэтому мы можем взять второй элемент здесь,но тогда ssort
должен быть хвост-рекурсивным в операторе let ... in ...
, это четвертый случай.
Но этот четвертый случай требует, чтобы ssort
был хвостовой рекурсивностью в "теле"let ... in ...
выражение.Это выражение ((:) x) (ssort delete xs)
.Таким образом, это третий случай.
В третьем случае выражение имеет форму t0 t1
, здесь с t0 = (:) x
и t1 = ssort delete xs
.Поскольку ssort
не встречается в t0
, здесь нет хвостовой рекурсии.