Angenommen, ich habe eine Liste mit Zahlen von 1 bis MAGIC_NUMBER - Gibt es eine Möglichkeit, dies vorher zu erklären?Wie verwende ich Konstanten in Haskell, um magische Zahlen zu vermeiden?
Antwort
können Sie algebraische Daten verwenden, in allen Berechnungen und einige benannten Werte verwenden, wenn sie wirklich „Magie“ sind, oder bauen der algebraischen Werte machen zu „magischen“ Zahlen und viele mehr:
class FlagsMask f where mask :: f -> Int
data Magics = Alpha | Beta | Gamma
deriving (Enum, Read, Show, Eq, Ord)
instance FlagsMask Magics where
mask m = 2^fromEnum m
data PermsFlag = FlagRead | FlagWrite | FlagExec | FlagSuper
-- [flagRead, flagWrite, flagExec] = [2^n | n <- [0..2]]
(flagRead : flagWrite : flagExec : _) = [2^n | n <- [0..]]
flagSuper = 16
instance FlagsMask PermsFlag where
mask FlagRead = flagRead
mask FlagWrite = flagWrite
mask FlagExec = flagExec
mask FlagSuper = flagSuper
*Main> map fromEnum [Alpha .. ] [0,1,2] it :: [Int] *Main> zip [Alpha .. ] [1..] [(Alpha,1),(Beta,2),(Gamma,3)] it :: [(Magics, Integer)]
Sicher. Da Haskell rein funktional ist, ist es viel einfacher, eine Konstante als eine Nicht-Konstante zu definieren.
magicNumber = 42
magicList = [1..magicNumber]
Chucks und onys Antworten sind korrekt. Es gibt eine Falle Ihnen bewusst sein sollten:
magicNum = 42
f magicNum = 'A'
f _ = 'B'
ist nicht das, was man erwarten könnte - magicNum
in zweiter Linie ist ein Muster, das alles paßt, genau wie f x = 'A'
. Verwenden Sie f x | x == magicNum = 'A'
.
Tatsächlich können Sie sogar Standardoperatoren auf diese Weise wieder binden. Wenn Sie zum Beispiel die Funktion 'f (==) a b = a == b 'definieren und dann' f div 8 4' aufrufen, ist das Ergebnis 2, nicht false. (Dies ist natürlich eine Art pathologische Angelegenheit.) – Chuck
Was meinen Sie mit "Zahlen deklarieren"? – ony
Ein sehr wichtiger Punkt, den Sie klären sollten: Wann kennen Sie die magische Zahl? Wenn Sie es zur Kompilierzeit wissen, hat Chuck unten die richtige Antwort. –