Почему GHC жалуется на неправильный тип? - PullRequest
0 голосов
/ 22 августа 2010

Эта маленькая функция проверяет (конечную) строку 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)

Может, я просто слишком глуп, чтобы понять, что пошло не так, но для меня это выглядит очень странно.

1 Ответ

5 голосов
/ 22 августа 2010

Посмотрите на тип maybe и подумайте, что он должен делать:

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

Если значение Maybe не содержит результата (т.е. Nothing), maybe возвращает аргумент b,

В противном случае - когда задано Just a - оно применяет данную функцию к действительному результату .Нам не нужно извлекать fromJust здесь.

Ваш код просто становится

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