解析器的函子

Functor for a parser

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

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

这对我来说很清楚,我们的解析器从类型 a 和剩余的未解析字符串中得到一个字符串是 return 表达式。

但是接下来我们要定义这个仿函数:

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

我完全迷路了。在我看来 parse p s 给出了类型 a 的解析表达式,但我不明白这个 fmap 实际上在做什么以及为什么它有意义。

希望哪位高手能指点一下。

谢谢!

给定一个解析器 pfmap fn p 将创建一个新的解析器,它解析与 p 相同的文本,然后将 fn 应用于输出。例如,如果你有一个解析器 parseOptionalNumber :: Parser (Maybe Int),你可以通过 parseNumber = fmap fromJust parseOptionalNumber 将它变成 parseNumber :: Parser Int(尽管你不想这样做,因为 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 在给定解析器 p.
  • 的输出 (a,c)

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

instance Functor Parser where
    fmap f inParser = Parser $ \inputStr ->
        case (parse inParser inputStr) of
            Nothing -> Nothing
            Just (result, leftoverString) -> Just (f result, leftoverString)