gpt4 book ai didi

haskell - 为什么 ParsecT 类型有 'u' 参数?

转载 作者:行者123 更新时间:2023-12-04 08:07:19 25 4
gpt4 key购买 nike

的文档秒差距states that u参数用于通过一元计算携带一些用户状态。但是同样的功能可以通过 ParsecT 来实现。 State 上的单子(monad)变压器单子(monad)。所以如果我的解析器不是有状态的,我不需要 u完全一致,但必须将其设置为 ()秒差距。向 ParsecT 添加非可选状态支持的基本原理是什么? ?

最佳答案

因为 ParsecT s () (State st) a 类型的解析器与 Parsec s st Identity a 类型的解析器的行为不同当涉及回溯时:

  • 当 parsec 在不消耗任何输入的失败解析后尝试替代时,用户状态会重置。
  • 但是底层的 Monad m不回溯;保留最终解析结果过程中发生的所有影响。

  • 考虑以下示例:
    {-# LANGUAGE FlexibleContexts #-}
    module Foo where

    import Control.Applicative
    import Control.Monad.State
    import Text.Parsec.Prim hiding ((<|>), State(..))
    import Text.Parsec.Error (ParseError)

    tick :: MonadState Int m => ParsecT s Int m ()
    tick = do
    lift $ modify (+1)
    modifyState (+1)

    tickTock :: MonadState Int m => ParsecT s Int m ()
    tickTock = (tick >> empty) <|> tick

    -- | run a parser that has both user state and an underlying state monad.
    --
    -- Example:
    -- >>> run tickTock
    -- (Right 1,2)
    run :: ParsecT String Int (State Int) () -> (Either ParseError Int, Int)
    run m = runState (runParserT (m >> getState) initUserState "-" "") initStateState
    where initUserState = 0
    initStateState = 0

    如您所见,底层状态单子(monad)注册了两个滴答声(来自尝试过的两种替代方案),
    而 Parsec monad 转换器的用户状态只保留了成功的一个。

    关于haskell - 为什么 ParsecT 类型有 'u' 参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27835214/

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