Frage

Nehmen Sie dieses Beispiel-Code (ignorieren es schrecklich ineffizient für den Moment ist)

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

Dies ist ein gemeinsames Muster, das ich über kommen immer in F #, ich brauche eine innere Funktion haben, der sich über einen gewissen Wert recurses - und ich brauche nur einmal diese Funktion ist in irgendeiner Weise es möglich, eine Lambda anrufen aus es selbst (einige magische Stichwort oder etwas)? Ich würde den Code gerne so etwas wie folgt aussehen:

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

Aber wie man erwarten könnte es gibt keine Möglichkeit, auf die anonyme Funktion in sich selbst zu beziehen, die benötigt wird, wo ich setzen ## RECURSE ##

War es hilfreich?

Lösung

Ja, es ist möglich, mit so genannten y-combinators (oder fixed-point combinators). Ex:

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" *)

Ich weiß nicht, Artikel für F #, aber diese Haskell Eintrag könnte auch hilfreich sein, .

Aber:. Ich würde sie nicht verwenden, wenn es eine Alternative ist - Sie sind ziemlich schwer zu verstehen,

Ihr Code (weglassen die Typenannotationen hier) ist ein Standard-Konstrukt und viel ausdrucks.

let listToString lst =

    let rec loop acc = function
        | []    -> acc
        | x::xs -> loop (acc ^ (string x)) xs

    loop "" lst

Andere Tipps

Beachten Sie, dass, obwohl Sie sagen, dass Sie die Funktion nur einmal verwenden, technisch verweisen Sie auf sie namentlich zweimal, weshalb es Sinn macht es einen Namen zu geben.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top