Возьмите этот пример кода (проигнорируйте его являющийся ужасно неэффективным в настоящий момент),
let listToString (lst:list<'a>) = ;;' prettify fix
let rec inner (lst:list<'a>) buffer = ;;' prettify fix
match List.length lst with
| 0 -> buffer
| _ -> inner (List.tl lst) (buffer + ((List.hd lst).ToString()))
inner lst ""
Это - общий шаблон, с которым я продолжаю сталкиваться в F#, у меня должна быть внутренняя функция, кто рекурсивно вызывает себя по некоторому значению - и мне только нужна эта функция однажды, должен там любым возможным путем назвать лямбду из него сам (некоторое волшебное ключевое слово или что-то)? Я хотел бы, чтобы код выглядел примерно так:
let listToString2 (lst:list<'a>) = ;;' prettify fix
( fun
(lst:list<'a>) buffer -> match List.length lst with ;;' prettify fix
| 0 -> buffer
| _ -> ##RECURSE## (List.tl lst) (buffer + ((List.hd lst).ToString()))
) lst ""
Но поскольку Вы могли бы ожидать, что нет никакого способа обратиться к анонимной функции в себе, который необходим, куда я поместил ##RECURSE##
Да, это возможно с использованием так называемых y-комбинаторов (или комбинаторы с фиксированной точкой
). Пример:
let rec fix f x = f (fix f) x
let fact f = function
| 0 -> 1
| x -> x * f (x-1)
let _ = (fix fact) 5 (* evaluates to "120" *)
Я не знаю статей по F #, но эта запись haskell также может быть полезна.
Но: Я бы не стал их использовать, если есть альтернатива - они довольно сложные чтобы понять.
Ваш код (опустите здесь аннотации типов) является стандартной конструкцией и гораздо более выразительной.
let listToString lst =
let rec loop acc = function
| [] -> acc
| x::xs -> loop (acc ^ (string x)) xs
loop "" lst
Обратите внимание, что, хотя вы говорите, что используете функцию только один раз, технически вы обращаетесь к ней по имени дважды, поэтому имеет смысл дать ей имя.