2009-06-03 21 views
6

我有一個檢查一個類型是否是另一個類型的子類型的函數:錯誤哈斯克爾處理與無論是單子

st :: Monad m => Map String Type -- ^type environment 
    -> Set (Type, Type) -- ^assumed subtypes 
    -> (Type, Type) -- ^we are checking if lhs <: rhs  
    -> m (Set (Type, Type)) 

我想要做的錯誤處理。我有以下定義:

instance Monad (Either String) where 
    return v = Right v 
    fail s = Left s 
    (Left s) >>= _ = Left s 
    (Right v) >>= f = f v 

有時候,我可以通過下述方法作爲第一任的結果做錯誤處理。例如,下面的函數工作,並讓我從調用導致消息「失敗」 ST內:

isSubType env cs t1 t2 = result where 
    result = case st env (S.empty) (t1, t2) of 
    Left msg -> Left msg 
    Right rel -> Right() 

現在,我在裏面ST和我想遞歸調用它。出於某種原因,下面的代碼,在ST嵌套深:

let do_t1 rel t1 = case st env rel (t1, t2) of 
     Left msg -> fail $ printf "type %s in the union is not a subtype\ 
          \ of the rhs, %s, because: %s" (renderType t1) 
          (renderType t2) (show msg) 
     Right rel -> return rel 

不類型檢查,但給我下面的錯誤:

No instance for (Monad (Either t)) 
     arising from a use of `st' 
        at src/TypedJavaScript/Types.hs:386:24-42 
    Possible fix: add an instance declaration for (Monad (Either t)) 

爲什麼治療ST的結果作爲外擦出火花'st'但不在裏面?我怎樣才能改變我的代碼,使其在內部也起作用?

+3

您似乎正在重新實施[Control.Monad.Error](http://www.haskell.org/ghc/docs/latest/html/libraries/mtl/Control-Monad-Error.html)? – ephemient 2009-06-03 02:16:25

回答

5

我認爲問題在於你打電話給show msg,你應該只使用msg。因此,編譯器無法推斷出你的意思是Either String;所有它知道的是,你有Either t約束Show t滿足。用msg代替show msg應該修復它。