gpt4 book ai didi

haskell - 解析器示例不适合我

转载 作者:行者123 更新时间:2023-12-02 21:32:47 25 4
gpt4 key购买 nike

我正在阅读 Real World Haskell,作为仿函数/单子(monad)的介绍,它给出了以下示例:

parseByte :: Parse Word8
parseByte =
getState ==> \initState ->
case L.uncons (string initState) of
Nothing ->
bail "no more input"
Just (byte,remainder) ->
putState newState ==> \_ ->
identity byte
where newState = initState { string = remainder,
offset = newOffset }
newOffset = offset initState + 1

(其余部分可以在页面下方约四分之一处阅读:http://book.realworldhaskell.org/read/code-case-study-parsing-a-binary-data-format.html)

对我来说没有任何意义的是,为什么这个函数不接受任何参数?我希望它接受一个包含要解析的文本的 Parse 对象,然后返回解析后的文本和一个新的 Parse 对象。相反,(正如我所见)它“神奇地”访问解析器,弹出一个字节,然后返回“修改后的”解析器。对象从哪里来?我已经盯着看了一天了,仍然不知道这个功能是如何工作的。

如果有任何指导,我们将不胜感激。

最佳答案

Parse 类型定义为

newtype Parse a = Parse
{ runParse :: ParseState -> Either String (a, ParseState)
}

因此,如果您想知道输入来自哪里,它就在类型的定义中!每个 Parse 值都包装了一个函数,然后我们在本例中使用 ==> 通过组合将两个 Parse 链接在一起,形成一个新的函数解析。然后最终使用 runParse 运行。该函数需要一个ParseState,定义为

data ParseState = ParseState
{ string :: L.ByteString
, offset :: Int64
} deriving (Show)

这是携带正在解析的字符串的内容。

您可以将 Parse 类型视为该类型的别名

ParseState -> Either String (a, ParseState)

这是一个如您所期望的函数。使用具有类型的 ==> 函数(删除了 newtype 包装器)

(==>)
:: (ParseState -> Either String (a, ParseState))
-> (a -> (ParseState -> Either String (b, ParseState)))
-> (ParseState -> Either String (b, ParseState))

然后我们可以将一个 Parse 并将其输入到另一个 Parse 中以创建一个新的 Parse。所有这些只不过是常规函数组合的花哨包装。它从初始状态调用 runParse 的地方获取输入。

关于haskell - 解析器示例不适合我,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25693056/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com