0

この小さな関数は、(有限の) Brainfuck 文字列の有効性をチェックします。[とのバランスが取れているかどうかをチェックし]ます。コードは非常に単純で、末尾再帰的に記述されています。

-- 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)

何がうまくいかなかったのかを理解するには私が愚かすぎるのかもしれませんが、これは私にとって非常に奇妙に見えます。

4

1 に答える 1

5

の型を見て、maybeそれが何をすべきかを考えてください:

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

多分値に結果が含まれていない場合 (つまりNothing)、引数をmaybe返しbます。

それ以外の場合Just a( が指定された場合)、指定された関数を有効な結果に適用します。fromJustここでは抽出は必要ありません。

あなたのコードはちょうど

maybe (return s) fail (validate s 0)
于 2010-08-22T15:34:40.970 に答える