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)
根据我自己的(有限的)经验,这是相当地道的。当您拥有双向模式同义词时,您将经常使用上述视图模式。
对于 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)
根据我自己的(有限的)经验,这是相当地道的。当您拥有双向模式同义词时,您将经常使用上述视图模式。