为什么 GHC 抱怨类型错误?
这个小函数检查(有限)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)
也许我太傻了,无法弄清楚出了什么问题,但这对我来说看起来很奇怪。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
查看
maybe
的类型并思考它应该做什么:如果 Maybe 值不包含结果(即
Nothing
),maybe
返回 <代码>b 参数。否则 - 当给出
Just a
时 - 它将给定的函数应用于有效结果。我们在这里不需要任何fromJust
提取。你的代码就变成了
Look at the type of
maybe
and think what it should do:If the maybe value contains no result (i.e.
Nothing
),maybe
returns theb
argument.Otherwise - when
Just a
is given - it applies the given function to the valid result. We don't need anyfromJust
extraction here.Your code just becomes