我是一個Haskell新手,我正在嘗試編寫一個解析器來評估一組簡單的Haskell表達式。然而,當我事先不知道它們是什麼類型時,我遇到了功能上的困難。如何解析Haskell中未知類型的函數?
假設,例如,我知道我想解析的字符串評估爲一個整數。以下是可能的字符串的一些可能性。
"succ 4"
"head [5,6,7]"
"sum [1,3,1]"
"length [a,b,c,d,e]"
"pred $ sum $ take 3 $ iterate succ 1"
天真什麼,我想這樣的事情最後一個例子做的是這樣的一個過程。
解析出功能
pred
,從事實,即它的類型爲(Enum a) => a -> a
,我的字符串代表一個整數,字符串(美元)之後的其餘部分仍然是一個整數推斷。解析出函數
sum
並推導出我正在嘗試評估一個整數列表。解析出函數
take
並推斷出我正在尋找一個整數和整數列表。解析出3並推斷字符串的其餘部分應該是一個整數列表。
解析出
iterate
並推斷出我正在尋找類型爲Int -> Int
的函數和一個整數。解析出
succ
和1
。執行評估。
問題在於,在流程的每個階段,我遇到的下一個對象都有很多可能的類型,如示例所示。所以我不能編寫一些通用的解析器來抽出一個函數,並留下代表它的參數(或參數)的字符串。但是如果我必須爲每種可能的函數編寫單獨的解析器,那麼它將很快成爲一場噩夢,尤其是當我必須查看多個變量的函數時。
我意識到它並沒有那麼糟糕,因爲許多函數都是爲幾種不同的類型定義的。但是,例如,如果我說「如果字符串以」succ「開頭,然後將它拉出來並將succ應用於評估字符串的其餘部分」,那麼它會抱怨我應該指定我正在處理Enum
類中的類型。但是當我處理不屬於該類的類型時,我遇到了麻煩。
完全披露:我在Graham Hutton的書中使用簡單的解析器來構建我想要構建的東西。所以也許答案是有更高級的解析器可以解決這類問題,而且我應該使用它。
解析Haskell表達式不應該與類型有關(除了'[1,3,9 :: Int]''中實際的_explicit annotations_之外)。只需將所有內容解析爲無類型,然後就可以考慮在生成的AST上實現類型統一。 - 顯然你不只是想解析代碼,而是解釋代碼,但這是另一個問題,實際上並不像動態語言那樣工作。像Hugs這樣的Haskell解釋器仍然能夠「編譯」一個類型檢查的AST。 – leftaroundabout