現在我正在嘗試使用 Haskell 撰寫一個玩具語言前端。
并且有兩個物體:
- 右值 - 變數和整數文字(例如)
- 左值 - 僅變數。
我認為在資料結構中描述這一點最自然的方式是:
data LValue = Var String
data RValue = Var String | Lit Int
(我真的認為這是最好的方法 - 由于詳盡的模式匹配,不夠冗長和嚴格)但是 ghc 顯示了錯誤:“多個 Var 宣告”。
所以問題是:在 Haskell 中描述我想要什么的最直接的方式是什么?
注:11年前有一個類似的問題,沒有很好的答案。但是 11 年有什么變化嗎? 一個屬于兩種不同型別的值建構式
還有一些其他方法可以在資料建構式中再次“打包”LValue(并且一次又一次地在非玩具語言中),如下所示:
data LValue = Var String
data RValue = LValue LValue | Lit Int
但我懷疑這是不是一個好方法:AST 轉換代碼變得過于冗長。
uj5u.com熱心網友回復:
我實際上認為你的提議是最好的:
newtype LValue = Var String -- newtype is slightly better here, I think
data RValue = LValue LValue | Lit Int
幾乎可以肯定的是,每當您將左值用作右值時,您都希望以統一的方式處理所有左值,因此此時您可能不需要或不想進行第二級模式匹配;換句話說,我聲稱這里的冗長會比你一開始想象的要少。
基本上有兩種選擇。首先是創建一個類:
newtype LValue = LVar String
data RValue = RVar String | Lit Int
class HasVariables ty where var :: String -> ty
instance HasVariables LValue where var = LVar
instance HasVariables RValue where var = RVar
這樣您就可以var用于構造LValues 或RValues。不過,在進行模式匹配時,您仍然需要在語法上區分它們。
二是做一個GADT:
data Side = L | R
data Value side where
Var :: String -> Value side
Lit :: String -> Value R
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/392565.html
下一篇:Haskell-用foldr計數
