Рекурсивные лямбды в F#

Возьмите этот пример кода (проигнорируйте его являющийся ужасно неэффективным в настоящий момент),

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##

7
задан duplode 15 July 2019 в 04:59
поделиться

2 ответа

Да, это возможно с использованием так называемых 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
17
ответ дан 6 December 2019 в 10:53
поделиться

Обратите внимание, что, хотя вы говорите, что используете функцию только один раз, технически вы обращаетесь к ней по имени дважды, поэтому имеет смысл дать ей имя.

1
ответ дан 6 December 2019 в 10:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: