在上一篇文章中,一位用户为 Haskell 提供了一个纯应用解析器的实现(代码最初来自这里)。下面是该解析器的部分实现:
{-# LANGUAGE Rank2Types #-}
import Control.Applicative (Alternative(..))
import Data.Foldable (asum, traverse_)
类型:
newtype Parser a = Parser {run :: forall f. Alternative f => (Char -> f ()) -> f a}
实例:
instance Functor Parser where
fmap f (Parser cont) = Parser $ \char -> f <$> cont char
instance Applicative Parser where
pure a = Parser $ \char -> pure a
(Parser contf) <*> (Parser cont) = Parser $ \char -> (contf char) <*> (cont char)
instance Alternative Parser where
empty = Parser $ \char -> empty
(Parser cont) <|> (Parser cont') = Parser $ \char -> (cont char) <|> (cont' char)
some (Parser cont) = Parser $ \char -> some $ cont char
many (Parser cont) = Parser $ \char -> many $ cont char
一些示例解析器:
item = Parser $ \char -> asum $ map (\c -> c <$ char c) ['A'..'z']
digit = Parser $ \char -> asum $ map (\c -> c <$ char (head $ show c)) [0..9]
string s = Parser $ \char -> traverse_ char s
不幸的是,我很难理解如何使用这个解析器实现。特别是,我不明白Char -> f ()
应该/可能是什么以及如何使用它来进行简单的解析,例如从输入字符串中额外增加一个数字。如果可能的话,我想要一个具体的例子。有人可以阐明一下吗?