В предыдущем сообщении пользователь предложил реализацию чисто аппликативного синтаксического анализатора для 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 ()
и как я мог бы использовать это для простого разбора, например. чтобы добавить цифру из входной строки. Я хотел бы конкретный пример, если это возможно. Может ли кто-нибудь пролить свет?
f
? - person Daniel Wagner   schedule 27.02.2016Char -> f ()
, этоforall f . Alternative f => (Char -> f ()) -> f a
. Вы не можете рассматривать здесь что-то типаChar -> f()
изолированно — вы должны рассматривать всю функцию сразу (из-за универсальной квантификации). Вы можете рассматривать этотParser
как наименьшую верхнюю границу всех (альтернативных) синтаксических анализаторов - он не реализует никаких функций, вместо этого он полагается на семантику любого типаf
, для которого в конечном итоге создается экземпляр. - person user2407038   schedule 27.02.2016