[英]Pattern Matching with Types in Haskell
假設我有一個類型,其中包含定義為以下各項的各種對象的坐標:
type Point = (Int, Int)
data Object = A Point
| B Point
| C Point
我想創建一個函數來檢查對象的重疊,像這樣
checkOverlap:: Object -> Point -> Bool
我只想定義一個適用於所有對象的函數,而不必指定“ checkOverlap(A點)(x,y)”,“ checkOverlap(B點)(x,y)”等。
我已經搜索了這個問題,但是我唯一能找到的解決方案是添加一個中間類型,該類型將收集所有不同的對象,以便您可以對該類型進行模式匹配。 但是,由於這是一項家庭作業,因此不允許修改大量代碼以適應這種新類型。
還有其他辦法嗎? 甚至沒有模式匹配。 似乎必須多次復制同一函數似乎是不好的編程。
如果允許更改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
添加為附加函數。 如果不想多次編寫getPoint
可以使用case
:
getPoint :: Object -> Point
getPoint obj = case obj of
A pt -> pt
B pt -> pt
C pt -> pt
如果您不想要其他功能,但仍然只想要checkOverlap
一個版本, 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
如我的評論所述,這是使用類型類的一種方法:
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)
考慮更改對象類型定義:
data ObjTy = A | B | C
data Object = Obj ObjTy Point
checkOverlap:: Object -> Point -> Bool
checkOverlap (Obj _ (x,y)) (u,v) = ...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.