2013-04-20 42 views
1

我正在寫一個簡單語言的解釋器作爲大學項目,並且有一些選項可用於編寫某些調試功能。我認爲這很簡單,但由於受挫讓我休息了一週左右,我已經回來處理這個問題。與IO和多態類型相結合的剛性類型錯誤

整個haskell文件大約250行,所以我不想發佈整個事情,但如果我沒有提供足夠的信息,請讓我知道。

我有這個功能

interpret_statement :: Prog -> (Var -> Val -> Vars -> o) -> Vars -> Stmt -> o 

其中(VAR - >纈氨酸 - >瓦爾 - > O)是調試功能 - 的2種可能性,我選擇

pure_passthrough :: Var -> Val -> Vars -> Vars -- does no IO 
write_debugging_info :: Var -> Val -> Vars -> IO Vars -- does IO 

我也有一個另一個功能

interpret_function :: Prog -> (Var -> Val -> Vars -> o) -> Vars -> [Stmt] -> Val 

其中包含一個線

interpret_function prog debug_function vars (x:xs) = interpret_function prog debug_function (interpret_statement prog debug_function vars x) xs 

,是3行一個給了我一個剛性類型錯誤,說

Expected type: Var -> Val -> Vars -> Vars 
Actual type: Var -> Val -> Vars -> o 

一切工作試圖引進IO之前完全沒問題。我這樣做是因爲這個網站上的一個單獨問題的答案,它建議我使用多態函數來告訴程序在運行時是否執行IO操作,具體取決於我是否收到命令行參數。

但現在它會導致問題,因爲我有幾個相關函數,我現在需要將多態變量傳入和傳出?哦,人性!我真的認爲我在Haskell球員身上變得更好,但是這一次讓我完全陷入困境。 「Actualy類型」Var - > Val - > Vars - > o如何是多態而不是特定的?

注:如果我需要包括更多信息,請讓我知道 - 我已經開始用盡可能少的,所以我不超載的人不必要的信息

回答

4

呼叫(interpret_statement prog debug_function vars x)是在一個位置,它必須返回Vars,它不能返回類型o

interpret_function,返回類型不依賴於o,所以即使您在返回IO單子調試功能傳遞的interpret_function的結果不是一個IO單子。

我Haskell是有點生疏,但我相信你可以改變interpret_function,以便其類型變爲

interpret_function :: (Monad m) => Prog -> (Var -> Val -> Vars -> m Vars) -> Vars -> [Stmt] -> m Val 

其中m將是要麼IO或一些瑣碎的單子(perhaps this one)。

現在具體情況的實施將走這樣的事情:

interpret_function prog debug_function vars (x:xs) = 
    do vars' <- interpret_statement prog debug_function vars x 
    return $ interpret_function prog debug_function vars' xs 
+0

唉唉現在我明白了。 interpret_function需要Vars類型在該位置。我*可以*包括單子,但有沒有其他方式來做到這一點?看起來好像我不得不改變程序中每一行的打字和/或模式匹配作爲包含這個IO的結果。當然......乞丐不能是挑剔者,但我可以保持希望...... – nebffa 2013-04-20 15:55:46

+1

@nebffa在這種情況下,看到你不能避免添加monad是相對容易的:你的函數'interpret_function'應該是可能會執行IO,但它確實會返回'Val',它是非IO類型的,所以它不能使用此結果類型執行任何IO。 – kosmikus 2013-04-20 16:09:16

+1

Monadic I/O確實傾向於「傳染性」。 – mpartel 2013-04-20 16:12:00