4

次の Haskell コードで、これをより簡潔に記述するにはどうすればよいでしょうか? 4 つの条件すべてをリストする必要がありますか、それともよりコンパクトなパターンで要約できますか? たとえば、手動でfromIntegralを指定することなく、float と int を追加する方法を既に知っている Haskell を利用する方法はありますか?

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

1 に答える 1

7

Haskell はaと;を追加する方法を知りません。タイプについて非常に具体的かつ明示的です。FloatInt

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

関数を定義しますtoFloatSig:

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

次に、次のように記述できます。

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

演算子で直接追加できるように、 classSignalのインスタンスを作成することも適切な場合があります。また、型をよりジェネリックにすることもできます。Num+

data (Num a) => Signal a = Signal a | Empty deriving (Show)
于 2009-11-11T15:48:22.383 に答える