Hier ist eine Möglichkeit, darüber nachzudenken. Überlegen Sie:
answer = 42
magic = 3
specialName :: Int -> String
specialName answer = "the answer to the ultimate question"
specialName magic = "the magic number"
specialName x = "just plain ol' " ++ show x
Können Sie sehen, warum das nicht funktioniert? answer
in der Musterübereinstimmung ist eine Variable, die sich von answer
im äußeren Bereich unterscheidet. Anstatt also, würden Sie diese wie schreiben:
answer = 42
magic = 3
specialName :: Int -> String
specialName x | x == answer = "the answer to the ultimate question"
specialName x | x == magic = "the magic number"
specialName x = "just plain ol' " ++ show x
In der Tat, das ist genau das, was los ist, wenn Sie Konstanten in einem Muster schreiben. Das heißt:
digitName :: Bool -> String
digitName 0 = "zero"
digitName 1 = "one"
digitName _ = "math is hard"
durch den Compiler zu etwas Gleichwertiges zu konvertiert wird:
digitName :: Bool -> String
digitName x | x == 0 = "zero"
digitName x | x == 1 = "one"
digitName _ = "math is hard"
Da Sie wollen gegen die Funktion (+)
eher gebunden passen als nur etwas zu dem Symbol binden (+)
, Sie‘ d müssen Sie den Code schreiben, wie:
instance Show (t -> t-> t) where
show f | f == (+) = "plus"
show f | f == (-) = "minus"
Aber dies würde erfordern, dass Funktionen für eq vergleichbar waren Qualität. Und das ist ein unentscheidbares Problem im Allgemeinen.
Sie könnten zähmen, dass Sie nur das Laufzeitsystem bitten, Funktionszeiger zu vergleichen, aber auf der Sprachebene hat der Haskell-Programmierer keinen Zugriff auf Zeiger. Mit anderen Worten, Sie können Verweise auf Werte in Haskell (*) nicht bearbeiten, sondern nur Werte selbst. Dies ist die Reinheit von Haskell und erhält referentielle Transparenz.
(*) MVar
s und andere solche Objekte in der IO
Monade sind eine andere Sache, aber ihre Existenz macht den Punkt nicht ungültig.
Das ist fantastisch, danke. (Und viel eleganter als die Lösung, die ich unten gegeben habe.) –
@Sean D: Es macht auch eine schöne Illustration, wo Ihr Mega Hack scheitern würde - überlegen Sie, was passieren würde, wenn es mit einem Operator auf 'Expression Integer' Werten verwendet würde . "Sum 6 2" ist nicht gleich "Literal 8", obwohl mein Code eine vollkommen sinnvolle Instanz von "Num" ist. –