使用PatternSynonyms
(显式双向形式),模式到表达式的方程实际上形成了一个函数,但是用大写字母拼写(为您提供正确类型的完全饱和的数据常量)。然后考虑(在GHC 8.10.2)
{-# LANGUAGE PatternSynonyms, ViewPatterns #-}
data Nat = Zero | Succ Nat deriving (Eq, Show, Read)
-- Pattern Synonyms as functions?
pattern Pred :: Nat -> Nat
pattern Pred n <- {- what goes here? -} where
Pred (Succ n) = n
pattern One = Succ Zero
zero = Pred One -- shows as Zero OK
那么我为pattern Pred n <- ???
的值到模式顶行放什么呢?或者我可以在模式匹配中不使用Pred n
?什么似乎工作(但我不明白为什么)是一个视图模式
pattern Pred n <- (Succ -> n) where ... -- seems to work, but why?
isZero (Pred One) = True
isZero _ = False
-- isZero (Pred One) ===> True ; isZero Zero ===> True
-- isZero (Succ One) ===> False; isZero One ===> False
在这里使用Pred
作为伪构造函数/模式看起来很甜蜜,因为它是一个内射函数。
考虑模式同义词的这种用法:
succ' :: Nat -> Nat
succ' (Pred n) = n
,其目的当然是返回实参的后继对象。
在这种情况下,很明显,当参数是k
时,那么变量n
必须绑定到Succ k
。基于这种直觉,我们需要找到一种模式,这种模式可以用来代替Pred n
:
succ' :: Nat -> Nat
succ' ({- bind n to Succ k -}) = n
你的视图模式就是这样做的。这样就可以了:
succ' :: Nat -> Nat
succ' (Succ -> n) = n
因此,我们必须定义
pattern Pred n <- (Succ -> n)
在我自己的(有限的)经验中,这是相当习惯的。当您有一个双向模式同义词时,您通常会像上面那样使用视图模式。