解析器的功能

问题描述 投票:0回答:1

作为家庭作业的一部分,我们正在Haskell中研究解析器。我们有此数据类型

newtype Parser a = Parser { parse :: String -> Maybe (a,String) } 

这对我来说很清楚,我们的解析器获取的字符串是类型a的返回表达式以及其余未解析的字符串。

但是接下来我们有这个函子定义:

  instance Functor Parser where
       fmap f p = Parser $ \s -> (\(a,c) -> (f a, c)) <$> parse p s

而我完全迷路了。在我看来,parse p s给出了类型a的解析表达式,但我无法理解此fmap实际在做什么以及为什么有意义。

希望有人可以给我一个线索。

谢谢!

haskell functor
1个回答
0
投票

给出解析器pfmap fn p将创建一个新的解析器,该解析器解析与p相同的文本,然后将fn应用于输出。例如,如果您有一个解析器parseOptionalNumber :: Parser (Maybe Int),则可以通过执行parseNumber :: Parser Int将其转换为parseNumber = fmap fromJust parseOptionalNumber(尽管您不想这样做,因为fromJust是部分的)。

至于实现,它是这样的:

  • 整个内容都包裹在Parser $ \s -> …中,这创建了一个新的解析器,该解析器在给定输入字符串的情况下执行s
  • [parse p s使用函数parse :: Parser a -> (String -> Maybe (a,String))(来自Parser a的定义)对输入字符串p运行输入解析器s,产生类型为Maybe (a,String)的输出。
  • (<$>)是函数fmap的同义词,但作为运算符而不是函数。它将左侧的功能映射到右侧的Maybe (a,String)输出。它映射的函数为\(a,c) -> (f a, c),它将在给定解析器f的输出(a,c)上运行给定函数p

希望这很有道理;如果不是这样,您可能会发现以不太紧凑的格式重写fmap更有用:

instance Functor Parser where
    fmap f inParser = Parser $ \inputStr ->
        case (parse inParser inputStr) of
            Nothing -> Nothing
            Just (result, leftoverString) -> Just (f result, leftoverString)
© www.soinside.com 2019 - 2024. All rights reserved.