2017-06-04 85 views
0

所以,我創建了一個數據型方程的交替情況模式匹配的

data Expr a = Const a 
    | Expr a :*: Expr a 

我定義了一個實例Eq對這種數據類型

instance (Eq m) => Eq (Expr m) where 
    Const a == Const b = a == b 
    (a :*: b) == (c :*: d) = ((a == c) && (b == d)) || ((a == d) && (b == c)) 

該定義是指順序並不重要當比較兩個表達式時。然而,當我使用模式匹配來寫一個函數,Expr是我能不能只寫

f (Const 1 :*: a) = ... 

而且必須寫

f (a :*: Const 1) = ... 

爲了趕上所有的情況下,即使如果我在哪裏比較兩者使用(==)它會返回true。

有沒有辦法只寫一個上面的表達式,讓Eq的實例照顧其餘的?模式匹配是否使用或需要Eq的實例?

回答

3

一個Eq實例對模式匹配沒有任何影響。 ==僅僅是一個庫函數,它檢查一個與實現結構不太相關的特定屬性,而模式匹配都是關於在其實際的ADT結構中解構一個類型。這就是說,僞造一些類似於你所問的東西是可能的,但我敢說實際做這件事不是一個好主意 - 不會伸縮,並且可能在以後引發一些奇怪的問題。

{-# LANGUAGE PatternSynonyms, ViewPatterns #-} 

matchConstFactor :: Expr a -> Maybe (a, Expr a) 
matchConstFactor (Const a :*: b) = Just (a, b) 
matchConstFactor (a :*: Const b) = Just (b, a) 
matchConstFact _ = Nothing 

pattern (:.*:) :: a -> Expr a -> Expr a 
pattern a :.*: b <- (matchConstFactor -> Just (a, b)) 
where a :.*: b = Const a :*: b 
3

是否有上面寫來表達只有一個,讓(EQ)的情況下采取其餘的工作方式?

是否圖案匹配甚至使用或需要的一個實例(EQ)

僅針對(數字,字符或字符串)文字匹配時。您可以看到https://www.haskell.org/onlinereport/exps.html#pattern-matching的3.17.2中的規則,並注意到案例7是唯一一個提及==的規則。

但是你可以使用視圖模式:

const1 (Const 1 :*: a) = Just a 
const1 (a :*: Const 1) = Just a 
const1 _ = Nothing 

f (const1 -> Just a) = ... 

這可能是,如果您需要在其他情況下,其他對稱性,我想不出在目前這種解決方案的太醜陋了。