了解 Text.ParserCombinators.ReadP.sepBy1
Understanding Text.ParserCombinators.ReadP.sepBy1
我对 sepBy1
的结果感到困惑
以下代码是 运行 在 ghci
λ> import Text.ParserCombinators.ReadP
λ> import Data.Char
λ> readP_to_S ((munch1 isAlpha) `sepBy1` (char '-')) "dish-dash-dosh"
[(["dish"],"-dash-dosh"),(["dish","dash"],"-dosh"),["dish","dash","dosh"],"")]
- 为什么输出不是
[(["dish","dash","dosh"],"")]
?
以下doctest
是唯一一个失败的。
-- |
-- >>> readP_to_S readValues "dish-dash-dosh"
-- [(V ["dish","dash","dosh"],"")
readValues :: ReadP Value
readValues = do
xs <- (munch isAlpha) `sepBy1` (char '-')
pure $ V xs
Main.hs:64: failure in expression `readP_to_S readValues "dish-dash-dosh"'
expected: [(V ["dish","dash","dosh"],"")
but got: [(V ["dish"],"-dash-dosh"),(V ["dish","dash"],"-dosh"),(V ["dish","dash","dosh"],"")]
我正在使用 ReadP
作为我数据的 Read
实例。 Read
实例的代码正在运行,但我很困惑。
没做过复杂的解析,总觉得运行ReadP
会return以单元素列表[(result,"")]
的形式输出,显然不是案.
data Value = V [String]
deriving Show
-- |
-- >>> read "dish-dash-dosh" :: Value
-- V ["dish","dash","dosh"]
--
instance Read Value where
readPrec = readP_to_Prec (const readValues)
- 是不是只有最后一个
[(Value,String)]
的snd
什么都没有的情况下read
才会成功,这个列表中的其他元素在任何地方都没有用?
我知道有其他选择 可以做到这一点。这个问题只是关于理解 sepBy
输出及其用法。
运行 ReadP
将 return 所有可能的解析。您可以通过指定 sepBy1
解析之后应该发生的事情来限制有效解析的数量,例如输入结束或其他语法元素。
例如,尝试这样的事情:
readValues = do
xs <- (munch isAlpha) `sepBy1` (char '-')
eof
pure $ V xs
附录...
ReadS
类型遵循经典 Hutton 和 Meijer 论文 Monadic Parsing in Haskell 中提出的单子解析的发展。从现有的少量文档中,我了解到 ReadP
实现了对所有备选方案的并行探索。对创建 ReadP
动作有很多支持,但对 ReadS
的支持不多,所以我认为您通过构建 ReadP
动作然后使用 [=18] 正确地使用了该库=] 最后。当我使用该模块时,我刚刚获取了 ReadS
操作的第一个匹配项(或者 returned 一个解析错误,如果它是空列表。)
ReadPrec
monad 用于支持优先级,它基本上是 ReaderT Int ReadP
-- 这里 Int
是当前优先级。同样,看起来您从 ReadP
解析器开始,然后使用 lift
或 readP_to_Prec
将其转换为 ReadPrec
操作。要 运行 你可以使用 readPrec_to_S
就像 ReadP
的情况一样。
我对 sepBy1
的结果感到困惑以下代码是 运行 在 ghci
λ> import Text.ParserCombinators.ReadP
λ> import Data.Char
λ> readP_to_S ((munch1 isAlpha) `sepBy1` (char '-')) "dish-dash-dosh"
[(["dish"],"-dash-dosh"),(["dish","dash"],"-dosh"),["dish","dash","dosh"],"")]
- 为什么输出不是
[(["dish","dash","dosh"],"")]
?
以下doctest
是唯一一个失败的。
-- |
-- >>> readP_to_S readValues "dish-dash-dosh"
-- [(V ["dish","dash","dosh"],"")
readValues :: ReadP Value
readValues = do
xs <- (munch isAlpha) `sepBy1` (char '-')
pure $ V xs
Main.hs:64: failure in expression `readP_to_S readValues "dish-dash-dosh"'
expected: [(V ["dish","dash","dosh"],"")
but got: [(V ["dish"],"-dash-dosh"),(V ["dish","dash"],"-dosh"),(V ["dish","dash","dosh"],"")]
我正在使用 ReadP
作为我数据的 Read
实例。 Read
实例的代码正在运行,但我很困惑。
没做过复杂的解析,总觉得运行ReadP
会return以单元素列表[(result,"")]
的形式输出,显然不是案.
data Value = V [String]
deriving Show
-- |
-- >>> read "dish-dash-dosh" :: Value
-- V ["dish","dash","dosh"]
--
instance Read Value where
readPrec = readP_to_Prec (const readValues)
- 是不是只有最后一个
[(Value,String)]
的snd
什么都没有的情况下read
才会成功,这个列表中的其他元素在任何地方都没有用?
我知道有其他选择 sepBy
输出及其用法。
运行 ReadP
将 return 所有可能的解析。您可以通过指定 sepBy1
解析之后应该发生的事情来限制有效解析的数量,例如输入结束或其他语法元素。
例如,尝试这样的事情:
readValues = do
xs <- (munch isAlpha) `sepBy1` (char '-')
eof
pure $ V xs
附录...
ReadS
类型遵循经典 Hutton 和 Meijer 论文 Monadic Parsing in Haskell 中提出的单子解析的发展。从现有的少量文档中,我了解到 ReadP
实现了对所有备选方案的并行探索。对创建 ReadP
动作有很多支持,但对 ReadS
的支持不多,所以我认为您通过构建 ReadP
动作然后使用 [=18] 正确地使用了该库=] 最后。当我使用该模块时,我刚刚获取了 ReadS
操作的第一个匹配项(或者 returned 一个解析错误,如果它是空列表。)
ReadPrec
monad 用于支持优先级,它基本上是 ReaderT Int ReadP
-- 这里 Int
是当前优先级。同样,看起来您从 ReadP
解析器开始,然后使用 lift
或 readP_to_Prec
将其转换为 ReadPrec
操作。要 运行 你可以使用 readPrec_to_S
就像 ReadP
的情况一样。