Data.List 插入单子
Data.List intercalate for monads
我正在使用 ReadP 模块编写一个小型解析器。我有这个表达:
cmdExpr = string "create" <|> string "add" <|> string "another alias" <|> ...
我想抽象掉 <|>
操作,但我不知道该怎么做。类似于 intercalate
:
getExpr cmds = intercalateM (<|>) $ map string cmds
cmdExpr = getExpr ["create", "add", "another alias", ...]
有什么想法吗?
您可以使用 choice
:
Prelude Text.ParserCombinators.ReadP> cmds = ["create", "add", "another alias"]
Prelude Text.ParserCombinators.ReadP> :t choice $ map string cmds
choice $ map string cmds :: ReadP String
你需要的是折叠。
<|>
不是列表元素,它是一个带有两个参数的关联函数。
你需要做这样的事情:
getExpr cmds = foldr1 (<|>) $ map string cmds
请注意,使用 foldr1
是一种快速而肮脏的修复方法:如果给定一个空列表,它将抛出异常。稳健的方法是将 foldr
与某种空解析器一起用作基本情况。
这是 asumMap
in Relude 的完美用例:
getExpr cmds = asumMap string cmds
cmdExpr = getExpr ["create", "add", "another alias", ...]
如果你不是用Relude而是用其他第三方库,那么还有其他相同的功能,比如altMap
in Util:
import Util (altMap)
getExpr cmds = altMap string cmds
cmdExpr = getExpr ["create", "add", "another alias", ...]
如果你想坚持使用Base,那么你可以分别使用asum
和map
,:
import Data.Foldable (asum)
getExpr cmds = asum $ map string cmds
cmdExpr = getExpr ["create", "add", "another alias", ...]
我正在使用 ReadP 模块编写一个小型解析器。我有这个表达:
cmdExpr = string "create" <|> string "add" <|> string "another alias" <|> ...
我想抽象掉 <|>
操作,但我不知道该怎么做。类似于 intercalate
:
getExpr cmds = intercalateM (<|>) $ map string cmds
cmdExpr = getExpr ["create", "add", "another alias", ...]
有什么想法吗?
您可以使用 choice
:
Prelude Text.ParserCombinators.ReadP> cmds = ["create", "add", "another alias"]
Prelude Text.ParserCombinators.ReadP> :t choice $ map string cmds
choice $ map string cmds :: ReadP String
你需要的是折叠。
<|>
不是列表元素,它是一个带有两个参数的关联函数。
你需要做这样的事情:
getExpr cmds = foldr1 (<|>) $ map string cmds
请注意,使用 foldr1
是一种快速而肮脏的修复方法:如果给定一个空列表,它将抛出异常。稳健的方法是将 foldr
与某种空解析器一起用作基本情况。
这是 asumMap
in Relude 的完美用例:
getExpr cmds = asumMap string cmds
cmdExpr = getExpr ["create", "add", "another alias", ...]
如果你不是用Relude而是用其他第三方库,那么还有其他相同的功能,比如altMap
in Util:
import Util (altMap)
getExpr cmds = altMap string cmds
cmdExpr = getExpr ["create", "add", "another alias", ...]
如果你想坚持使用Base,那么你可以分别使用asum
和map
,
import Data.Foldable (asum)
getExpr cmds = asum $ map string cmds
cmdExpr = getExpr ["create", "add", "another alias", ...]