Рекурсивная функция:
let rec listMerge (l1 : 'a list) (l2 : 'a list) =
if l1.IsEmpty then l2
elif l2.IsEmpty then l1
else l1.Head :: l2.Head :: listMerge l1.Tail l2.Tail
Теперь, если я не ошибаюсь, это на самом деле не выполняет хвостовой вызов, он просто может выглядеть так, если не учитывать, что ::
является правильным ассоциативным.
Затем у меня сложилось впечатление (из чего-то, что я читал, но не смог найти сейчас), что это можно легко преобразовать в хвостовую рекурсию, используя дополнительный fun
или что-то в этом роде.
Итак, возможно ли это? Код?
Мой ответ: Итак, вот как я изменил функции благодаря ответам ниже:
let listMerge l1 l2 =
let rec mergeLoop (l1 : 'a list) (l2 : 'a list) acc =
if l1.IsEmpty then (List.rev acc) @ l2
elif l2.IsEmpty then (List.rev acc) @ l1
else mergeLoop l1.Tail l2.Tail (l2.Head :: l1.Head :: acc)
mergeLoop l1 l2 []
match
, у меня также есть версия, в которой это используется, хотя я думаю, что эта версия более читабельна, чтение вслух почти на простом английском... Однако IL совсем другой, мне интересно, должен ли я опубликовать еще один вопрос, задающий что более эффективно. - person hyde   schedule 31.10.2012match
,let
,use
,fun
,function
и т. д.) более практично для функционального кода. Это также позволит вам делать более сложные вещи, которыеif
просто не могут. - person Ramon Snir   schedule 31.10.2012Head
иTail
, которые могут генерировать исключения, когда вы могли бы использовать сопоставление с образцом, чтобы заставить компилятор доказать правильность вашего кода в этом отношении. - person J D   schedule 05.11.2012match
бросаетMatchFailureException
лучше, чемHead
илиTail
бросаетArgumentException
, если в логике есть ошибка? Извините, если я кажусь упрямым, я полностью заmatch
, когда это дает дополнительную ценность, я просто не вижу дополнительной ценности в данном случае. - person hyde   schedule 05.11.2012match
выброситьMatchFailureException
, компилятор выдаст предупреждение. В этом случае компилятор доказывает, чтоmatch
никогда не вызовет исключения, поэтому во время компиляции вы знаете, что ваш код никогда не выйдет из строя таким образом. - person J D   schedule 05.11.2012