2016-07-11 8 views
1

Ich habe Haskell für eine Woche studiert und versucht, einige echte Weltfunktionen selbst zu schreiben. Mein Ziel ist es, die Geldsumme in Bezug auf die jeweiligen Münzen und die Menge dieser Münzen auszudrücken. Aber ich bin mir nicht sicher, ob ich "funktional" denke, wenn ich Funktionen schreibe. Beispielcode ist unten;Ausdrücken der Geldsumme in Bezug auf Änderungen

changes = [1,2,5,10,25,50] 

makechanges n cs = if n `div` (last cs) > 0 
        then (coin_amount, last cs) : makechanges (n - coin_amount * current_coin) (init cs) 
        else makechanges n (init cs) 
        where coin_amount = n `div` (last cs) 
         current_coin = last cs 

Beispiel Ausgabe ist

makechanges 126 changes 
[(50,2),(25,1),(1,1)] 

Gibt es eine FP Weise beabsichtigte Funktion zu schreiben? Ich fühle mich wie diese Funktion ist nur die Umwandlung der imperativen Funktion, danke im Voraus.

+3

Eine offensichtliche Verbesserung wäre es, die 'changes' Liste rückgängig zu machen. Listen sind asymmetrisch, 'last' und' init' sind teuer, 'head' und' tail' sind billig. –

+0

Danke für diesen Vorschlag, ich habe die Struktur der verknüpften Listen der Haskell-Listen völlig vergessen. –

+1

Mein Stilvorschlag ist es, die Teilfunktionen 'head, tail' auch zu vergessen und einfach bei der Mustererkennung zu bleiben. Ich gebe auch das n.m. Vorschlag, die Liste umzukehren: Beginnen Sie mit der größeren Münze. – chi

Antwort

1

würde eine linke Falte Lösung sein:

change :: (Foldable t, Integral a) => a -> t a -> [(a, a)] 
change total coin = foldl go (const []) coin total 
    where 
    go run c x = if x < c then run x else (c, x `div` c): run (x `mod` c) 

dann:

\> change 126 [1, 2, 5, 10, 25, 50] 
[(50,2),(25,1),(1,1)] 
+0

Da ich seit einer Woche arbeite (nicht in voller Tag-Nacht-Zeit), Faltbar, gehen und laufen klingelt keine Glocke für jetzt. Aber sicher werde ich diese Lösung weiter studieren und neu betrachten. –