[英]Haskell: Understanding the bind operator (>>=) for Monads
I have the following function: 我有以下功能:
parse :: String -> Maybe Token
And I am trying to implement the following function: 我正在尝试实现以下功能:
maketokenlist :: String -> Maybe [Token]
The function returns Nothing if there is a token that was not able to be parsed (ie parse returns Nothing if the token is not an integer or an arithmetic operator), otherwise it returns a list of Tokens. 如果存在无法解析的标记,则该函数返回Nothing(即,如果该标记不是整数或算术运算符,则parse返回Nothing),否则它将返回一个标记列表。
As Maybe is an instance of the Monad type class, I have the following approach: 由于Maybe是Monad类型类的实例,因此我采用以下方法:
maketokenlist str = return (words str) >>= parse
I convert the string into a list of individual tokens (eg "2 3 +" becomes ["2","3","+"] , and then map the parse function over each string in the list. 我将字符串转换为单个标记的列表(例如“ 2 3 +”变为[“ 2”,“ 3”,“ +”],然后将解析函数映射到列表中的每个字符串上。
Since the Monad instance for lists is defined as: 由于列表的Monad实例定义为:
instance Monad [] where
return x = [x]
xs >>= f = concat (map f xs)
fail _ = []
However, say that I had the list of strings [2, 3, "+", "a"] and after mapping parse over each element using >>= I get [Just 2, Just 3, Just (+), Nothing], as "a" cannot be parsed. 但是,说我有一个字符串列表[2,3,“ +”,“ a”],并且使用>> =在每个元素上映射解析之后,我得到了[Just 2,Just 3,Just(+),Nothing] ,因为无法解析“ a”。 Is there a way to make the function maketokenlist return Nothing using just the >>= operator? 有没有办法仅使用>> =运算符使maketokenlist函数不返回任何内容? Any insights are appreciated. 任何见解都表示赞赏。
If parse :: String -> Maybe Token
, then: 如果parse :: String -> Maybe Token
,则:
traverse parse :: [String] -> Maybe [Token]
This version of traverse
(which I have specialized to act on lists as the Traversable
instance and Maybe
as the Applicative
instance) may indeed be implemented using (>>=)
: 确实可以使用(>>=)
实现此版本的traverse
(我专门在列表上作为Traversable
实例, Maybe
作为Applicative
实例(>>=)
:
listMaybeTraverse parse [] = pure []
listMaybeTraverse parse (s:ss) =
parse s >>= \token ->
listMaybeTraverse parse ss >>= \tokens ->
pure (token:tokens)
I have chosen the names parse
, s
, and token
to show the correspondence with your planned usage, but of course it will work for any appropriately-typed functions, not just parse
. 我选择了名称parse
, s
和token
来显示与您计划的用法的对应关系,但是它当然适用于任何适当类型的函数,而不仅仅是parse
。
The instance of Monad
for lists does not make an appearance in this code. 用于列表的Monad
实例不在此代码中出现。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.