【发布时间】:2019-07-15 20:28:17
【问题描述】:
我有以下功能:
parse :: String -> Maybe Token
我正在尝试实现以下功能:
maketokenlist :: String -> Maybe [Token]
如果存在无法解析的标记,则该函数返回 Nothing(即,如果标记不是整数或算术运算符,则 parse 返回 Nothing),否则返回 Token 列表。
由于 Maybe 是 Monad 类型类的一个实例,我有以下方法:
maketokenlist str = return (words str) >>= parse
我将字符串转换为单个标记的列表(例如 "2 3 +" 变为 ["2","3","+"] ,然后将解析函数映射到列表中的每个字符串。
由于列表的 Monad 实例被定义为:
instance Monad [] where
return x = [x]
xs >>= f = concat (map f xs)
fail _ = []
但是,假设我有字符串列表 [2, 3, "+", "a"] 并且在使用 >>= 映射解析每个元素后,我得到 [Just 2, Just 3, Just (+) , Nothing],因为“a”无法解析。有没有办法只使用 >>= 运算符使函数 maketokenlist 返回 Nothing?任何见解都值得赞赏。
【问题讨论】:
-
[2, 3, "+", "a"],这既不是一个列表,也不是任何在 Haskell 中有意义的构造。列表必须由单一类型组成,例如[a]。所以你可以有[2,3]或["+","a"]。重新考虑问题,然后重试。 -
return将其参数包装在 monad 中,>>=立即将其解包。所以return (words str) >>= parse等价于parse (words str)。您是否有理由需要使用>>=,而不是maketokenlist str = map parse (words str)?
标签: haskell functional-programming monads