2016-05-05 5 views

Antwort

2

Hier ist ein besserer Weg, das gleiche zu tun:

updateA : Int -> Rec -> Rec 
updateA x rec = { rec | a = x } 

-- Similarly for b, c 

Jetzt können Sie die folgende tun, vorausgesetzt, Sie bereits einen Wert haben rec : Rec Sie aktualisieren möchten:

myUpdatedRec : Rec 
myUpdatedRec = 
    rec 
    |> updateA 7 
    |> updateB 19 

Sie können jetzt Aktualisieren Sie eine beliebige Anzahl von Feldern durch Zusammenführen |> updateX ....

+0

Ich mag das viel besser. – lifebalance

2

Sie möchten eine Funktion schreiben, die eine variable Anzahl von unterschiedlich typisierten Parametern hat. Das ist in dynamisch typisierten Sprachen (Javascript, Python, Ruby) üblich, aber in typisierten Sprachen normalerweise nicht erlaubt. Ulme erlaubt es nicht. Sie

updateRec : Rec -> Maybe Int -> Maybe Int -> Maybe Int -> Rec 
updateRec r a b c = 
    { r 
    | a = a |> Maybe.withDefault r.a 
    , b = b |> Maybe.withDefault r.b 
    , c = c |> Maybe.withDefault r.c 
    } 

Wenn die Datensatzfelder sind alle vom gleichen Typ (hier Int):

Sie können parameterswith der Maybe Typ, das Verständnis Nothing als „fehlendes Argument“, eine variable Anzahl von unterschiedlich typisierte emulieren akzeptieren könnte ein List Int statt:

updateRec : Rec -> List Int -> Rec 
updateRec r fields = 
    case fields of 
    [a] -> { r | a = a } 
    [a,b] -> { r | a = a, b = b } 
    [a,b,c] -> { r | a = a, b = b, c = c } 
    _ -> r 

ich mag diese Lösung nicht, weil Sie es wird unbemerkt fehlschlagen, wenn Sie versehentlich eine Liste mit 0 oder 4+ Elemente liefern. Wenn diese Funktion für Sie trotzdem hilfreich ist, wäre es vielleicht besser, List Int anstelle von Rec zu verwenden.

+0

Offenbar, auch wenn JS, benötigen Sie zusätzlichen Code wie in diesem Artikel - http://javascript.crockford.com/www_svendtofte_com/code/curried_javascript/. Deine erste Version wird für mich funktionieren, danke. – lifebalance

+0

Ich erhalte einen Fehler im eml-repl wie folgt: Das 2. Argument zur Funktion 'updateRec' verursacht eine Nichtübereinstimmung. updateRec r 3 ^ Funktion 'updateRec' erwartet das zweite Argument zu sein: ' Vielleicht number' Aber es ist: 'number' – lifebalance

+1

klingt, als ob Sie versuchen, einen Anruf zu tun' updateRec r 3 ... 'aber du musst es' updateRec r (Just 3) 'nennen. –

1

Elms Record Update-Syntax scheint genau das zu sein, wonach Sie suchen. Sie „pass in“ der Datensatz, den Sie aktualisiert werden sollen, r unten, und Sie können einen Datensatz mit dem, was Felder zurückkehren Sie jedes Feld angeben geändert werden sollen, ohne dass:

ex1 = { r|a = 1 } 
ex2 = { r|b = 2, c = 3 } 

Sie brauchen nicht zu schaffen eine Reihe von zusätzlichen Funktionen für die Aktualisierung nur bestimmter Felder zu bestimmten Zeiten, weil Elms Satz Update-Syntax diese verallgemeinerte Funktion ist.

+0

Ok. Nur für theoretische Zwecke akzeptiert 'ex1' im obigen Code keine Parameter, richtig? Oder wie würden Sie 'ex1' und' ex2' aufrufen? – lifebalance

+1

Rechts. Ich würde argumentieren, dass Sie keine zusätzlichen Funktionen für die allgemeine Aktualisierung definieren müssen. Wie für "ex1" und "ex2" oben, sind dies nur Beispiele und unnötig, abhängig von Ihrer Situation. Sie könnten etwas in einer "Let" -Anweisung tun, um Ihren Code zu bereinigen. Andernfalls denke an '{r | a = 1}' als Wert für sich selbst, der überall dort verwendet werden kann, wo Werte verwendet werden. –

+0

Kühl. Habe ich, danke. – lifebalance

Verwandte Themen