我正在為一種小型編程語言撰寫一個解釋器,AST 看起來像這樣:
data Value a = IntVal a Int | FloatVal a Float
data Expr a = AddExpr a (Value a) (Value a) | MulExpr a (Value a) (Value a)
我使用引數a來存盤每個術語的行號。有些函式采用帶注釋的術語,有些采用空術語(替換a為unit),如下所示:
myFunction :: Value Int -> ...
myFunction = ...
myOtherFunction :: Value () -> ...
myOtherFunction = ...
但是,我發現這個替代方案更清楚一點:
type Annotated b = b Int
type Bare b = b ()
然后,我可以像這樣重寫前兩個函式:
myFunction :: Annotated Value -> ...
myFunction = ...
myOtherFunction :: Bare Value -> ...
myOtherFunction = ...
這很好用,但是我還需要為具有相同特征的串列型別定義同義詞:
type MyList a = [Value a]
現在,我想定義一個帶有注釋的函式,MyList如下所示:
myOtherOtherFunction :: Annotated MyList -> ...
myOtherOtherFunction = ...
但是,這不起作用。錯誤說The type synonym ‘MyList’ should have 1 argument, but has been given none。為什么這不起作用?有沒有更好的方法來定義這些型別?也許有一些擴展?
uj5u.com熱心網友回復:
默認情況下,Haskell 有點迂腐,即必須始終完全應用型別同義詞,也就是說,如果MyList不直接將其應用于具體的型別引數,就無法提及,因此您不能將Annotated MyList. 此限制的原因是部分應用的型別同義詞可能會被濫用以形成圖靈完備的語言。哎呀……這對編譯器來說會很痛苦。
也就是說,顯然這對于?? 來說有點愚蠢Annotated MyList,這是在通過對完全不引人注目的兩個簡單替換解決之后解決的[Value Int],所以這應該可行,不是嗎?確實如此,但您需要啟用語法擴展:
{-# LANGUAGE LiberalTypeSynonyms #-}
myOtherOtherFunction :: Annotated MyList -> ...
myOtherOtherFunction = undefined
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/316851.html
標籤:哈斯克尔
