No-fun/puzzlement 以模式同义词作为函数

No-fun/puzzlement with pattern synonyms as functions

对于 PatternSynonyms (explicitly bidirectional form),pattern-to-expr 方程实际上形成了一个函数但拼写为大写(前提是您最终得到正确的完全饱和数据构造类型)。然后考虑(在 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 作为 pseudo-constructor/pattern 看起来不错,因为它是一个内射函数。

考虑模式同义词的这种用法:

succ' :: Nat -> Nat
succ' (Pred n) = n

当然,这里的意图是 return 参数的后继者。

在这种情况下很明显,当参数为 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)

根据我自己的(有限的)经验,这是相当地道的。当您拥有双向模式同义词时,您将经常使用上述视图模式。