与Haskell中的类型匹配的模式

时间:2014-10-19 00:14:42

标签: haskell types pattern-matching

假设我有一个包含各种对象坐标的类型:

   type Point = (Int, Int)

   data Object = A Point
               | B Point
               | C Point

我想创建一个检查对象重叠的函数,比如

   checkOverlap:: Object -> Point -> Bool

我想只定义一个适用于所有对象的函数,而不必指定" checkOverlap(A point)(x,y)"," checkOverlap(B point)(的x,y)"等等。

我已经搜索了问题,但我能找到的唯一解决方案是添加一个中间类型,它将收集所有不同的对象,以便您可以在该类型上进行模式匹配。但是,由于这是一项家庭作业,我不允许修改大块代码以适应这种新类型。

还有其他方法吗?也许甚至没有模式匹配。看起来糟糕的编程似乎不得不多次复制相同的函数。

3 个答案:

答案 0 :(得分:5)

如果您允许更改Object的定义,则可以使用记录语法:

type Point = (Int, Int)

data Object = A { getPoint :: Point, ... }
            | B { getPoint :: Point, ... }
            | C { getPoint :: Point, ... }

checkOverlap :: Object -> Point -> Bool
checkOverlap obj pt = doSomething (getPoint obj) pt

如果您不允许更改定义并且提取点是一项常见任务,您只需添加getPoint作为附加功能即可。如果您不想多次写case,可以使用getPoint

getPoint :: Object -> Point
getPoint obj = case obj of 
                 A pt -> pt
                 B pt -> pt
                 C pt -> pt

如果您不想要其他功能,但仍然只需要checkOverlap的一个版本,则可以将case移至checkOverlap

checkOverlap :: Object -> Point -> Bool
checkOverlap obj pt = let opt = case obj of {A a -> a; B b -> b; C c -> c} 
                      in -- use opt and pt

答案 1 :(得分:1)

在我的评论中,这是一种使用类型类的方法:

type Point = (Int, Int)
data Obj = A Point | B Point | C Point


class HasPoint p where
    point :: p -> Point


instance HasPoint (Obj) where
    point (A p) = p
    point (B p) = p
    point (C p) = p


checkOverlap :: (HasPoint ob) => ob -> Point -> Bool
checkOverlap ob otherPoint =
    undefined
      where
          myPoint = point ob

somethingA = checkOverlap (A (1,1)) (1,1)
somethingB = checkOverlap (B (1,1)) (1,1)

答案 2 :(得分:0)

考虑更改对象类型定义:

data ObjTy = A | B | C

data Object = Obj ObjTy Point

checkOverlap:: Object -> Point -> Bool
checkOverlap (Obj _ (x,y)) (u,v) = ...