[英]Matching polymorphic data in Haskell
假設我們有一個名為Stuff的數據:
data Stuff = Stuff1 Int
| Stuff2 Int
| Stuff3 Int
sumStuff :: [Stuff] -> Int
sumStuff [] = 0
sumStuff ((Stuff1 x):xs) = x + sumStuff xs
sumStuff ((Stuff2 x):xs) = x + sumStuff xs
sumStuff ((Stuff3 x):xs) = x + sumStuff xs
sumStuff' :: [Stuff] -> Int
sumStuff' [] = 0
sumStuff' ((_ x):xs) = x+sumStuff xs
如何在沒有模式匹配的情況下匹配所有類型,如sumStuff'中的錯誤定義?
先感謝您!
如果它與您的示例一樣同源,您可以對數據結構采取不同的方法:
data StuffType = Stuff1 | Stuff2 | Stuff3 deriving (Eq, Show)
data Stuff a = Stuff StuffType a deriving (Eq, Show)
extractStuff :: Stuff a -> a
extractStuff (Stuff _ a) = a
sumStuff :: Stuff Int -> Int
sumStuff = sum . map extractStuff
我甚至將Stuff
包含的值設置為多態,以防你想存儲String
或更多的Stuff
。 這種方法允許您在需要時對StuffType
進行模式匹配,但如果不需要,可以使用單個模式案例。
您還可以使用記錄來定義它,以避免模式匹配:
data Stuff a = Stuff { stuffType :: StuffType, extractStuff :: a } deriving (Eq, Show)
和sumStuff
具有相同的定義,但您不需要手動定義extractStuff
。
我認為您正在尋找鏡頭它們允許您查看數據類型並查看或更改包含的值,在這種情況下,它們可以簡化模式匹配。 這是一個開始了解它們的好地方。
用鏡頭寫這個可能看起來像:
data Stuff = Stuff1 { _stuff :: Int } |
Stuff2 { _stuff :: Int } |
Stuff3 { _stuff :: Int }
makeLenses ''Stuff
sumStuff [] = 0
sumStuff (x:xs) = x ^. stuff + sumStuff xs
在這種情況下,鏡頭可能有點矯枉過正,因為你只能使用記錄語法。 即
data Stuff = Stuff1 {stuff :: Int } |
Stuff2 {stuff :: Int } |
Stuff3 {stuff :: Int }
sumStuff [] = 0
sumStuff (x:xs) = stuff x + sumStuff xs
或sumStuff = foldr ((+) . stuff) 0
希望這可以幫助。
你真的不能。 你能做的最好的事情就是這樣寫:
toInt :: Stuff -> Int
toInt (Stuff1 x) = x
toInt (Stuff2 x) = x
toInt (Stuff3 x) = x
sumStuff :: [Stuff] -> Int
sumStuff [] = 0
sumStuff (x:xs) = toInt x + sumStuff xs
基本上你是隱藏了toInt
函數后面的模式匹配。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.