2016-05-05 4 views
0

Ich habe folgende Art:Fall Paar - Spiel nur der gleiche Wert

MyData = MI Integer | MD Double | MC Char. 

Nun, ich möchte in der Lage sein kann, was folgende:

(MI _, MI _) -> "ok, these are the same value" 
(MI _, MD _) -> "fail, first is MI, and second is MD" 

Wie es zu tun? Wie du denkst, möchte ich nicht zu viele Fälle schreiben ... Kannst du mir einen Weg empfehlen?

+2

wha Es ist Ihr Problem, das Sie nur in eine Funktionsdefinition einbinden müssen (denken Sie daran, '=' nicht '->' zu verwenden, beginnen Sie mit dem Schreiben Ihrer Typsignatur - und vielleicht haben Sie eine ['lyah'] (http: // learnyouahaskell .com) offen für Unternehmen Sie – epsilonhalbe

+0

BTW - Ihre Typdefinition ist falsch - Sie müssen 'Daten' vor dieser Zeile setzen. – epsilonhalbe

Antwort

1

Eine Lösung in „reinen“ Haskell (das ohne viele Spracherweiterungen ist, etc.) wäre zunächst den MyData zu MyDataType ein < abzuzubilden> Elemente (die zum Beispiel kann ein Integer sein) und die Typen vergleichen . Der Vorteil besteht darin, dass Sie andere Vergleiche für den Typ durchführen können. Zum Beispiel:

import Data.Function(on) 

data MyData = MI Integer | MD Double | MC Char 

myDataType :: MyData -> Integer 
myDataType (MI _) = 0 
myDataType (MD _) = 1 
myDataType (MC _) = 2 

areEqualTypes :: (MyData,MyData) -> Bool 
areEqualTypes (a,b) = (==) `on` myDataType 

altough für diesen Fall ist es nicht viel Wert hinzugefügt, wenn Sie später für ein Tupel von drei, ob zwei Arten überprüfen möchten gleich sind, wird es in weniger Code führen. Zum Beispiel:

atLeastOneEqualType :: (MyData,MyData,MyData) -> Bool 
atLeastOneEqualType (a,b,c) = ta == tb || ta == tc || tb == tc 
    where ta = myDataType a 
      tb = myDataType b 
      tc = myDataType c 
1

Eine weitere Möglichkeit, eine Berechnung mit einem Begriff des Scheiterns zu erreichen Either String x als Ergebnistyp zu verwenden.

In diesem Fall ist eine Funktion

data MyData = MI Integer | MD Double | MC Char 
      deriving (Show) 

equivalence :: MyData -> MyData -> Either String Bool 
equivalence (MI _) (MI _) = Right True 
equivalence (MD _) (MD _) = Right True 
equivalence (MC _) (MC _) = Right True 
equivalence a  b  = Left $ "Type mismatch: " ++ show (a,b) 

jetzt ist dies eher uninteressant, aber eine zukünftige Version

equivalence :: MyData -> MyData -> Either String Bool 
equivalence (MI a) (MI b) = Right $ a == b 
equivalence (MD a) (MD b) = Right $ a == b 
equivalence (MC a) (MC b) = Right $ a == b 
equivalence  a  b = Left $ "Type mismatch: " ++ show (a,b) 
1

Wahrscheinlich am einfachsten die einfachste Art und Weise sein könnte, ist, man muss nur vier Voraussetzungen schreiben müssen

equalType :: (MyData, MyData) -> Bool 
equalType (MC _, MC _) = True 
equalType (MI _, MI _) = True 
equalType (MD _, MD _) = True 
equalType _ = False 
-1
cname_MyData :: MyData -> String 
cname_MyData (MI _) = "MI" 
cname_MyData (MD _) = "MD"  
cname_MyData (MC _) = "MC" 

doThing :: MyData -> MyData -> Either String a 
doThing (MI i1) (MI i2) = Right (...) 
doThing (MD d1) (MD d2) = Right (...) 
doThing (MC c1) (MC c2) = Right (...) 
doThing x1 x2 = Leftt ("Tried to doThing with " ++ 
     cname_MyData x1 ++" and " ++ cname_MyData x2) 
Verwandte Themen