2015-08-24 11 views
10

Bu nedenle, bir dizi düğüm türü içeren ağaçları temsil eden bir tür istiyorum. Örtüşen kümeler üzerinde tanımlanmış benzer ağacı temsil eden türleri de severim. Bu, Yazılı AST sorununun başka bir sürümüdür. Bir ayrıştırma ağacı Lit s veya Var s ama hiçbir Hole s içerebilirHaskell'de polimorfik bir ağaç etiketlenirken sözdizimsel dağınıklığı nasıl azaltabilirim?

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

: düğüm-tiplerinin benim havuz olduğunu varsayalım. Şablon olarak adlandırılan ikinci tür bir ağaç, Lit s, Var s veya Hole s içerebilir.

İşleri kolaylaştırmak için, Add adı verilen tek bir tür yineleme düğümü vardır.

data Parse = A Lit | B Var 
data Template = C Lit | D Var | E Hole 
data Tree a = Leaf a 
      | Add (Tree a) (Tree a) 

yüzden şimdi verilerini ilan edebilir ve hala üzerinde desen maç, tek sorun sözdizimsel dağınıklığı olduğunu olabilir.

ParseLit = A . Lit 
TempLit = C . Lit 

Açıkçası kurucular (değil tip) ait kompozisyonlar için takma adlar Haskell yasal değildir:

aParse = Add (A Lit 3) (B Var "x") 
aTemplate = Add (C Lit 4) (E Hole 3) 
fun (Add (A lit) (B var) = ... 

Ne istiyorum benzer bazı şekerdir. Fakat bunu yazmanın en temiz yolu, mümkün olduğunca fazla kazan levhadan kaçınmaktır?

cevap

14

PatternSynonyms dil uzantısı burada yardımcı olabilir. Bu desen için isim belirtmenizi sağlar: (örnekteki gibi) çift yönlü ve tek yönlü:

{-# LANGUAGE PatternSynonyms #-} 

pattern ParseLit x = A (Lit x) 

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

desen eş anlamlı iki tatlar vardır. Çift yönlü olanlar da kurucular olarak kullanılabilir:

*Main> :t ParseLit 
ParseLit :: Int -> Parse 

*Main> ParseLit 77 
+0

Oh vay. Tam olarak aradığım şey bu. Teşekkürler. – Amoss

İlgili konular