2012-06-19 47 views
8

Tôi đã đọc phần giới thiệu GADT here và tôi đã tìm thấy ý tưởng hạn chế lập trình để tạo đúng loại cây cú pháp tuyệt vời và tôi đưa ý tưởng này vào trình thông dịch tính toán lambda đơn giản của tôi, sau đó tôi nhận ra rằng tôi không thể phân tích một chuỗi thành cây cú pháp này, bởi vì một hàm phân tích cú pháp cần phải trả về các kiểu cây cú pháp khác nhau, tùy thuộc vào đầu vào. Dưới đây là một ví dụ:cách phân tích chuỗi thành cây cú pháp bằng GADT

{-# LANGUAGE GADTs #-} 
data Ident 
data Lambda 
data Application 

data Expr a where 
    Ident :: String -> Expr Ident 
    Lambda :: Expr Ident -> Expr a -> Expr Lambda 
    Application :: Expr a -> Expr a -> Expr Application 

Trước khi sử dụng GADTs, tôi đã sử dụng này:

data Expr = Lambda Expr Expr 
      | Ident String 
      | Application Expr Expr 

GADTs là lợi thế lớn ở đây, bacuse bây giờ tôi không thể tạo cây cú pháp không hợp lệ như Lambda (Application ..) ...

Nhưng với GADT, tôi không thể phân tích cú pháp chuỗi và tạo cây phân tích cú pháp. Dưới đây là phân tích cú pháp cho Lambda, ident, và các biểu thức Ứng dụng:

ident :: Parser (Expr Ident) 
ident = ... 

lambda :: Parser (Expr Lambda) 
lambda = ... 

application :: Parser (Expr Application) 
application = ... 

Bây giờ vấn đề là:

expr = choice [ident, application, lambda] 

Điều này rõ ràng không hoạt động, vì mỗi phân tích cú pháp đang trở lại loại khác nhau.

Vì vậy, có cách nào để phân tích chuỗi và tạo cây cú pháp, với GADT không?

Trả lời

8

Bạn có thể sử dụng GADT để tạo loại có chứa Expr a đối với một số không rõ a.

data AnyExpr where AnyExpr :: Expr a -> AnyExpr 

Trong tình huống mà bạn không muốn hạn chế Expr đến một loại hình cụ thể, sử dụng AnyExpr.

anyExpr :: Parser (Expr a) -> Parser AnyExpr 
anyExpr p = fmap AnyExpr p 

expr :: Parser AnyExpr 
expr = choice [anyExpr ident, anyExpr application, anyExpr lambda] 
+0

đó là một ý tưởng tuyệt vời, cảm ơn! nhưng tôi vẫn tự hỏi liệu chúng ta có cách nào khác để làm những gì tôi muốn hay không và liệu điều tôi đang làm là một ý hay hay ... – sinan

+2

@sinan - điều này là tốt, nhưng cách tiếp cận khác là xác định hai AST, một cho đầu ra phân tích cú pháp và một cho thực sự làm việc với. Cây đầu ra phân tích cú pháp sẽ không được phân tách và AST hoạt động sẽ sử dụng GADT như bạn đã triển khai. –

Các vấn đề liên quan