簡體   English   中英

在Haskell中匹配多態數據

[英]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.

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