Haskell:了解Monad的绑定运算符(>> =)

时间:2019-07-15 20:28:17

标签: haskell functional-programming monads

我具有以下功能:

parse :: String -> Maybe Token

我正在尝试实现以下功能:

maketokenlist :: String -> Maybe [Token]

如果存在无法解析的令牌,则该函数返回Nothing(即如果令牌不是整数或算术运算符,则parse返回Nothing),否则返回令牌列表。

由于也许是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函数不返回任何内容?任何见解都会受到赞赏。

1 个答案:

答案 0 :(得分:5)

如果parse :: String -> Maybe Token,则:

traverse parse :: [String] -> Maybe [Token]

此版本的traverse(我专门在列表中充当Traversable实例,Maybe作为Applicative实例)实际上可以使用{{ 1}}:

(>>=)

我选择了名称listMaybeTraverse parse [] = pure [] listMaybeTraverse parse (s:ss) = parse s >>= \token -> listMaybeTraverse parse ss >>= \tokens -> pure (token:tokens) parses来显示与您计划的用法的对应关系,但是它当然适用于任何适当类型的函数,而不仅仅是token

列表parse的实例未在此代码中显示。