所以我想要一个表示包含一组节点类型的树的类型。我也想要代表在重叠集合上定义的相似树的类型。这是Typed AST问题的另一个版本。假设我的节点类型池为:

data Lit = Lit Int
data Var = Var String
data Hole = Hole Int

解析树可以包含LitVar,但不能包含Hole。第二种称为模板的树可以包含LitVarHole

为了简单起见,有一种类型的递归节点称为Add
data Parse = A Lit | B Var
data Template = C Lit | D Var | E Hole
data Tree a = Leaf a
            | Add (Tree a) (Tree a)

因此,现在我可以声明数据,并且仍可以对其进行模式匹配了,唯一的问题是语法困惑。
aParse = Add (A Lit 3) (B Var "x")
aTemplate = Add (C Lit 4) (E Hole 3)
fun (Add (A lit) (B var) = ...

我想要一些类似于的糖:
ParseLit = A . Lit
TempLit = C . Lit

显然,在Haskell中,构造函数(不是类型)的别名是不合法的。但是,编写此代码的最干净的方法是什么,避免尽可能多的重复使用?

最佳答案

PatternSynonyms 语言扩展可以在这里提供帮助。它使您可以为模式指定别名:

{-# LANGUAGE PatternSynonyms #-}

pattern ParseLit x = A (Lit x)

someFunc :: Parse -> Int
someFunc p = case p of
    ParseLit x -> x
    _ -> 0

模式同义词有两种形式:双向(如示例中)和单向。双向的也可以用作构造函数:
*Main> :t ParseLit
ParseLit :: Int -> Parse

*Main> ParseLit 77

09-25 15:31