Angenommen, ich habe eine Reihe von Funktionen mit dem Typ Action -> Int -> Int
(oder gleichwertig), wobei Action
eine Summenart ist und jede Funktion nur mit nur einer der Varianten funktioniert.So kombinieren Sie Haskell-Muster effizient
data Action = Reset | Increment | Decrement
tryReset :: Action -> Int -> Int
tryReset a i = case a of
Reset -> 0
_ -> i
tryIncrement :: Action -> Int -> Int
tryIncrement a i = case a of
Increment -> i + 1
_ -> i
tryDecrement :: Action -> Int -> Int
tryDecrement a i = case a of
Decrement -> i - 1
_ -> i
Gibt es eine Möglichkeit, die Funktionen zu definieren (z. B. wie composedTogether
) in einem einzigen Fall Ausdruck zu führen (optimisedCase
) anstelle der mehrfachen Fall Ausdrücke (multipleCase
)?
composedTogether :: Action -> Int -> Int
composedTogether a = tryReset a . tryIncrement a . tryDecrement a
optimisedCase :: Action -> Int -> Int
optimisedCase Reset i = 0
optimisedCase Increment i = i + 1
optimisedCase Decrement i = i - 1
multipleCase :: Action -> Int -> Int
multipleCase a i = case a of
Decrement -> i - 1
_ -> case a of
Increment -> i + 1
_ -> case a of
Reset -> 0
_ -> i
Oder ist ghc bereits magisch und optimiert dies automatisch?
Manchmal tut der Optimierer zu viel! Ich habe neulich über eine Stunde gebraucht, um herauszufinden, wie ich GHC davon abhalten kann, einen Thunk zuzuweisen, um eine Freigabe zu erhalten, die ich nicht brauchte, wenn ich keine Zuteilung wollte! – dfeuer