【问题标题】:How can I reduce syntactic clutter when tagging a polymorphic tree in Haskell?在 Haskell 中标记多态树时,如何减少语法混乱?
【发布时间】:2015-08-24 16:47:41
【问题描述】:

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

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

解析树可以包含Lits 或Vars,但不能包含Holes。称为模板的第二种树可以包含Lits、Vars 或Holes。

为了简单起见,这里有一种称为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 中,构造函数(不是类型)组合的别名显然是不合法的。但是,什么是最简洁的编写方式,尽可能避免使用样板代码?

【问题讨论】:

    标签: haskell pattern-matching


    【解决方案1】:

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-20
      • 2015-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多