Werfen wir einen Datentyp mit vielen Konstrukteuren betrachten:„Pattern Matching“ von algebraischen Typ Daten Konstrukteurs
data T = Alpha Int | Beta Int | Gamma Int Int | Delta Int
Ich möchte eine Funktion schreiben, zu überprüfen, ob zwei Werte mit dem gleichen Konstruktor erzeugt werden:
sameK (Alpha _) (Alpha _) = True
sameK (Beta _) (Beta _) = True
sameK (Gamma _ _) (Gamma _ _) = True
sameK _ _ = False
Wartung sameK
macht nicht viel Spaß, es kann nicht leicht auf Korrektheit überprüft werden. Wenn zum Beispiel neue Konstruktoren zu T
hinzugefügt werden, ist es leicht zu vergessen, sameK
zu aktualisieren. Ich weggelassen eine Zeile ein Beispiel zu geben:
-- it’s easy to forget:
-- sameK (Delta _) (Delta _) = True
Die Frage ist, wie Textvorschlag zu vermeiden, in sameK
? Oder wie stellt man sicher, dass es nach allen T
Konstruktoren sucht?
Die Abhilfe, die ich gefunden ist für jeden des Konstrukteurs separate Datentypen zu verwenden, Data.Typeable
abzuleiten, und eine gemeinsame Typklasse erklärt, aber ich weiß nicht, diese Lösung gefällt, weil es viel weniger lesbar ist und ansonsten nur eine einfache algebraische Art funktioniert für mich:
{-# LANGUAGE DeriveDataTypeable #-}
import Data.Typeable
class Tlike t where
value :: t -> t
value = id
data Alpha = Alpha Int deriving Typeable
data Beta = Beta Int deriving Typeable
data Gamma = Gamma Int Int deriving Typeable
data Delta = Delta Int deriving Typeable
instance Tlike Alpha
instance Tlike Beta
instance Tlike Gamma
instance Tlike Delta
sameK :: (Tlike t, Typeable t, Tlike t', Typeable t') => t -> t' -> Bool
sameK a b = typeOf a == typeOf b
Vielen Dank für Ihre Antwort. Alle deine Antworten waren nützlich. – sastanin