簡體   English   中英

Haskell中的模式匹配數據類型。捷徑?

[英]Pattern matching data types in Haskell. Short cuts?

在下面的Haskell代碼中,如何更簡潔地編寫它? 是否有必要列出所有四個條件,還是可以通過更緊湊的模式進行總結? 例如,有沒有一種方法可以利用Haskell已經知道如何添加一個浮點數和一個int,而不必手動指定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)))

哈斯克爾知道如何添加一個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)

Signal作為Num的實例也可能是合適的,這樣您就可以使用+運算符直接添加它們。 此外,您可以使類型更通用:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM