cen*_*980 2 monads haskell functional-programming
我有以下功能:
parse :: String -> Maybe Token
Run Code Online (Sandbox Code Playgroud)
我正在尝试实现以下功能:
maketokenlist :: String -> Maybe [Token]
Run Code Online (Sandbox Code Playgroud)
如果存在无法解析的标记,则该函数返回Nothing(即,如果该标记不是整数或算术运算符,则parse返回Nothing),否则它将返回一个标记列表。
由于Maybe是Monad类型类的实例,因此我采用以下方法:
maketokenlist str = return (words str) >>= parse
Run Code Online (Sandbox Code Playgroud)
我将字符串转换为单个标记的列表(例如“ 2 3 +”变为[“ 2”,“ 3”,“ +”],然后将解析函数映射到列表中的每个字符串上。
由于列表的Monad实例定义为:
instance Monad [] where
return x = [x]
xs >>= f = concat (map f xs)
fail _ = []
Run Code Online (Sandbox Code Playgroud)
但是,假设我有字符串列表[2,3,“ +”,“ a”],并使用>> =在每个元素上映射解析之后,我得到了[Just 2,Just 3,Just(+),Nothing] ,因为无法解析“ a”。有没有办法仅使用>> =运算符使maketokenlist函数不返回任何内容?任何见解都表示赞赏。
如果为parse :: String -> Maybe Token,则:
traverse parse :: [String] -> Maybe [Token]
Run Code Online (Sandbox Code Playgroud)
实际上,可以使用以下方式实现此版本traverse(我专门负责在列表上作为Traversable实例以及Maybe作为Applicative实例)(>>=):
listMaybeTraverse parse [] = pure []
listMaybeTraverse parse (s:ss) =
parse s >>= \token ->
listMaybeTraverse parse ss >>= \tokens ->
pure (token:tokens)
Run Code Online (Sandbox Code Playgroud)
我选择了名称parse,s并token显示了与您计划的用法的对应关系,但是它当然适用于任何适当类型的函数,而不仅仅是parse。
Monadfor列表的实例在此代码中未出现。