Haskell pattern matching data types. Short cuts?

In the following Haskell code, how can this be written more succinctly? Do I need to list all four conditions, or can they be summarized using a more compact template? For example, is there a way I can use Haskell, already knowing how to add float and int, without having to manually specify 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))) 
+4
source share
1 answer

Haskell does not know how to add Float and Int ; it is very specific and clear about types:

 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 

Define the toFloatSig function:

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

Then you can write:

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

It may also be appropriate to make a Signal instance of the Num class so that you can add it directly using the + operator. In addition, you can make the type more general:

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

All Articles