문제

This little function checks a (finite) Brainfuck string for validity. It check's whether the [ and ] are balanced. The code is very straightforward and written to be tail-recursive:

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

Now, GHC complains about typing issues:

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)

Maybe I'm just too silly to figure out what went wrong, but this looks very weird for me.

도움이 되었습니까?

해결책

Look at the type of maybe and think what it should do:

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

If the maybe value contains no result (i.e. Nothing), maybe returns the b argument.

Otherwise - when Just a is given - it applies the given function to the valid result. We don't need any fromJust extraction here.

Your code just becomes

maybe (return s) fail (validate s 0)
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top