4 Stimmen

Musterübereinstimmende Datentypen in Haskell. Abkürzungen?

Wie kann dies im folgenden Haskell-Code prägnanter formuliert werden? Ist es notwendig, alle vier Bedingungen aufzulisten, oder können diese durch ein kompakteres Muster zusammengefasst werden? Gibt es zum Beispiel eine Möglichkeit, den Vorteil zu nutzen, dass Haskell bereits weiß, wie man einen float und einen int addiert, ohne dass man manuell angeben muss fromIntegral ?

data Signal = SignalInt Int | SignalFloat Float | Empty deriving (Show)

sigAdd :: Signal -> Signal -> Signal
sigAdd (SignalInt a) (SignalInt b) = SignalInt (a + b)
sigAdd (SignalInt a) (SignalFloat b) = SignalFloat ((fromIntegral a) + b)
sigAdd (SignalFloat a) (SignalInt b) = SignalFloat (a + (fromIntegral b))
sigAdd (SignalFloat a) (SignalFloat b) = SignalFloat (a + b)

main :: IO ()
main = do
  putStrLn (show (sigAdd (SignalFloat 2) (SignalInt 5)))

7voto

Thomas Punkte 160390

Haskell tut ノット wissen, wie man eine Float und ein Int Sie ist sehr spezifisch und explizit in Bezug auf Typen:

Prelude> (5 :: Int) + 3.5

<interactive>:1:13:
    No instance for (Fractional Int)
      arising from the literal `3.5' at <interactive>:1:13-15
    Possible fix: add an instance declaration for (Fractional Int)
    In the second argument of `(+)', namely `3.5'
    In the expression: (5 :: Int) + 3.5
    In the definition of `it': it = (5 :: Int) + 3.5

Definieren Sie eine Funktion toFloatSig :

toFloatSig (SignalInt a) = fromIntegral a
toFloatSig (SignalFloat a) = a

Dann können Sie schreiben:

sigAdd (SignalInt a) (SignalInt b) = SignalInt (a + b)
sigAdd sa sb = SignalFloat (toFloatSig sa + toFloatSig sb)

Es könnte auch angebracht sein, die Signal eine Instanz der Num Klasse so dass Sie sie direkt mit der Option + Betreiber. Außerdem könnte man den Typ allgemeiner gestalten:

data (Num a) => Signal a = Signal a | Empty deriving (Show)

0 Stimmen

> sigAdd sa sb = SignalFloat (toFloatSig a + toFloatSig b) Sollte dies "...(toFloatSig sa + toFloatSig sb)" sein? Danke!

0 Stimmen

Warum gilt die "Sehr starke Konvention, keine Einschränkungen für Datenkonstruktoren zu haben" hier nicht? Ich tauche gerade in Haskell ein und habe über diese Regel gelesen, also bin ich neugierig, ob sie auf Ihr Beispiel zutrifft (und wenn nicht - warum)

1 Stimmen

@Al.G. Es wäre vielleicht besser, die Einschränkung einfach wegzulassen. Dann Signal entwickelt sich im Grunde zu Maybe die nützlich sein könnten. Aber ich bin auch kein Experte...

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X