2010-08-22 84 views
0

這個小函數檢查(有限)Brainfuck字符串的有效性。它檢查[]是否平衡。該代碼是非常簡單,編寫爲尾遞歸:爲什麼GHC抱怨錯誤的類型?

-- checks Brainfuck for validity. 
validateBrainfuck :: Monad m => String -> m String 
validateBrainfuck s = maybe (return s) (fail . fromJust) (validate s 0) where 
    validate :: String -> Int -> Maybe String -- Here inversed: String means error 
    validate (']':_) 0 = Just "Too many closing brackets" 
    validate (']':xs) c = validate xs (pred c) 
    validate ('[':xs) c = validate xs (succ c) 
    validate (x :xs) c = validate xs  c 
    validate []  0 = Nothing 
    validate []  _ = Just "Too many opening brackets" 

現在,GHC抱怨打字的問題:

Brainfuck.hs:62:58: 
    Couldn't match expected type `Maybe String' 
      against inferred type `[Char]' 
     Expected type: Maybe (Maybe String) 
     Inferred type: Maybe String 
    In the third argument of `maybe', namely `(validate s 0)' 
    In the expression: 
     maybe (return s) (fail . fromJust) (validate s 0) 

也許我只是太傻找出什麼地方出了錯,但這對我來說看起來很奇怪。

+0

另外,怎麼樣'不是String()'的類型簽名?那麼你並沒有扭轉定義明確的語義。另外,任一個都是Monad(好,有點...參見'Control.Monad.Error'),所以你甚至不需要「失敗」。 – jrockway 2010-08-25 04:09:49

+0

我想盡可能通用類型簽名。所以我做到了。 – fuz 2010-08-25 04:40:55

回答

5

看的maybe類型,並認爲它應該做的:

maybe :: b -> (a -> b) -> Maybe a -> b 

如果可能的值不包含任何結果(即Nothing),maybe返回b說法。

否則 - 當給出Just a - 它適用於給定函數到有效的結果。這裏我們不需要任何fromJust提取。

你的代碼只是變得

maybe (return s) fail (validate s 0) 
+0

你是對的。 (多麼不好的問題)......對我感到羞恥。 – fuz 2010-08-22 15:36:23

相關問題