它是什麼,一個類型的類約束參數限制在構造函數,所以你不能模式匹配?
當您在顯式構造函數上進行模式匹配時,您將提交給特定的數據類型表示。這種數據類型不是在類的所有實例之間共享的,所以不可能用這種方式編寫適用於所有實例的函數。
相反,你需要不同的行爲,你想與每個實例相關聯,就像這樣:現在
class C a where
toString :: a -> String
draw :: a -> String
instance C MyType1 where
toString v = "MyType1"
draw (MyObj11 x) = "11"
draw (MyObj12 x y) = "12"
instance C MyType2 where
toString v = "MyType2"
draw (MyObj22 x y) = "22"
data MyType1 = MyObj11 Int | MyObj12 Int Int
data MyType2 = MyObj21 Int | MyObj22 Int Int
test :: C a => a -> String
test x = draw x
你原來test
功能的分支機構分佈在實例之中。
一些替代技巧涉及使用class-associated data types(向編譯器證明數據類型在所有實例之間共享)或view patterns(它允許您概括模式匹配)。
查看模式
我們可以使用視圖模式來清理模式匹配和類型的類的實例,有點之間的連接,讓我們通過模式上的共享匹配近似的圖案跨實例匹配類型。
下面是一個例子,我們寫了一個函數,有兩種情況,讓我們對類中的任何事物進行模式匹配。
{-# LANGUAGE ViewPatterns #-}
class C a where
view :: a -> View
data View = One Int
| Two Int Int
data MyType1 = MyObj11 Int | MyObj12 Int Int
instance C MyType1 where
view (MyObj11 n) = One n
view (MyObj12 n m) = Two n m
data MyType2 = MyObj21 Int | MyObj22 Int Int
instance C MyType2 where
view (MyObj21 n) = One n
view (MyObj22 n m) = Two n m
test :: C a => a -> String
test (view -> One n) = "One " ++ show n
test (view -> Two n m) = "Two " ++ show n ++ show m
注意->
語法如何讓我們在每一個實例回調到合適的view
功能,查找每類自定義數據類型的編碼,以模式匹配就可以了。
設計的挑戰是要拿出捕獲所有的行爲變種你感興趣的視圖類型。
在你原來的問題,你想每一個構造有不同的行爲,所以實際上沒有使用視圖類型的原因(在每個實例中直接調度到該行爲已經足夠好)。
如果haskell的類是可關閉的 - 也就是說,您可以爲每個實現指定行爲,這可能是有意義的。但是Haskell類是開放的 - 當'instance SomeClass SomeoneElsesType whereString v =「mwahahahah」''時,如果給定'SomeoneElsesType'類型的值,'test'應該做些什麼?答案是處理這個問題的正確方法。 – rampion 2011-04-22 21:43:20
這個問題對我來說似乎很明顯:它會做任何模式匹配說它應該。如果沒有模式匹配,就會像其他任何這樣的情況一樣出現這樣的錯誤。我沒有看到區別。 – mentics 2011-04-22 22:44:37