这个问题(从 5 年前开始)问“为什么所有递归模式同义词都被拒绝?” 它的例子仍然被拒绝。用户指南说“模式同义词不能递归定义。”
我有一个被接受的递归模式同义词(GHC 8.10.2)。我可以调用它,它会循环 - 不足为奇。那么为什么它会编译?/这样的事情是否有合理的用例?
基于2016 年论文第 2.3 节“多态模式同义词”中的示例的代码。
data JoinList a = JNil | Unit a | JoinList a `JoinTree` JoinList a deriving (Eq, Read, Show)
我正在尝试定义模式同义词Nil
。显然JNil
是一场比赛。而且,和任何提供所有叶子的JNil ``JoinTree`` JNil
任意嵌套都是。JoinTree
JNil
pattern Nil :: JoinList a
pattern Nil <- JNil
where Nil = Nil `JoinTree` Nil -- huh?
wot = Nil `JoinTree` Nil -- these all compile
wotwot Nil = ()
wotwotwot = wotwot Nil
wotwotwotwot = wotwot wot
尝试调用wot
循环,不足为奇。试图打电话wotwotwot
抱怨Non-exhaustive patterns in function wotwot
。
完全披露:我正在玩的/我知道这不起作用[另见下文]是:
pattern Nil = JNil -- base case matcher, and builder
where Nil <- Nil `JoinTree` Nil -- recursion on the matcher, not the builder
-- but can't put `<-` equations after where
以下被拒绝Recursive pattern synonym definition
- 这是我所期望的
pattern NilRec <- NilRec `JoinTree` NilRec
where NilRec = JNil
无论如何,这是行不通的:它需要首先匹配NilRec = JNil
作为基本情况。
要回答@Noughtmare 的 q“你会如何建议......”对他的回答的评论,我想根据上面的“我在玩什么”写 decl(是的,我知道这是目前非法的语法);并将其脱糖到具有两种情况的匹配器中,依次尝试:
case arg of
{ JNil -> ...
; Nil `JoinTree` Nil -> ...
}
请注意,这些案例中的每一个都有一个来自 type 的最外层数据构造函数JoinList
。因此,递归使用Nil
是受保护/中介的,就像通过 ViewPattern 的任何方法一样。(这是 q 5 年前的问题。)换一种说法:我认为编译器可以从pattern ... = ... where ... <- ...
.