它是什么,一个类型的类约束参数限制在构造函数,所以你不能模式匹配?
当您在显式构造函数上进行模式匹配时,您将提交给特定的数据类型表示。这种数据类型不是在类的所有实例之间共享的,所以不可能用这种方式编写适用于所有实例的函数。
相反,你需要不同的行为,你想与每个实例相关联,就像这样:现在
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