Parsing 在Haskell中组合解析器

Parsing 在Haskell中组合解析器,parsing,haskell,applicative,Parsing,Haskell,Applicative,我得到了以下解析器 newtype Parser a = Parser { parse :: String -> Maybe (a,String) } instance Functor Parser where fmap f p = Parser $ \s -> (\(a,c) -> (f a, c)) <$> parse p s instance Applicative Parser where pure a = Parser $ \s ->

我得到了以下解析器

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

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

instance Applicative Parser where
   pure a = Parser $ \s -> Just (a,s)
   f <*> a = Parser $ \s ->
     case parse f s of
       Just (g,s') -> parse (fmap g a) s'
       Nothing -> Nothing

instance Alternative Parser where
   empty = Parser $ \s -> Nothing
   l <|> r = Parser $ \s -> parse l s <|> parse r s

 ensure :: (a -> Bool) -> Parser a -> Parser a
 ensure p parser = Parser $ \s ->
    case parse parser s of
      Nothing -> Nothing
      Just (a,s') -> if p a then Just (a,s') else Nothing

 lookahead :: Parser (Maybe Char)
 lookahead = Parser f
   where f [] = Just (Nothing,[])
         f (c:s) = Just (Just c,c:s)

 satisfy :: (Char -> Bool) -> Parser Char
 satisfy p = Parser f
   where f [] = Nothing
         f (x:xs) = if p x then Just (x,xs) else Nothing

 eof :: Parser ()
 eof = Parser $ \s -> if null s then Just ((),[]) else Nothing

 eof' :: Parser ()
 eof' = ???
newtype Parser a=Parser{parse::String->Maybe(a,String)}
实例函子解析器,其中
fmap fp=Parser$\s->(\(a,c)->(fa,c))parse ps
实例应用程序解析器,其中
纯a=解析器$\s->Just(a,s)
f a=解析器$\s->
案例解析
只是(g,s')->parse(fmap g a)s'
无->无
实例替代解析器,其中
empty=解析器$\s->Nothing
l r=Parser$\s->parse l s parse r s
确保::(a->Bool)->解析器a->解析器a
确保p parser=parser$\s->
的实例解析解析器
无->无
Just(a,s')->如果pa那么Just(a,s')其他什么都没有
lookahead::解析器(可能是Char)
lookahead=f解析器
其中f[]=Just(Nothing,[])
f(c:s)=刚好(刚好c,c:s)
满足:(Char->Bool)->解析器Char
满足p=f
其中f[]=无
f(x:xs)=如果px,那么就(x,xs)其他什么都没有
eof::解析器()
eof=Parser$\s->如果为空,则只需((),[])其他内容
eof'::解析器()
eof'=???
我需要编写一个新的解析器
eof'
,它完全执行
eof
的功能,但只使用给定的解析器和
上述函子/应用程序/替代实例。我被困在这个问题上,因为我没有组合解析器的经验。有人能帮我吗

为了更容易理解,我们可以用一个等式伪代码来编写它,同时替换和简化定义,使用Monad理解来清晰和简洁


Monad理解就像列表理解一样,只适用于任何
MonadPlus
类型,而不仅仅是
[]
;当与
do
表示法紧密对应时,例如
[(fa,s')|(a,s')谢谢你!我被这个提示卡住了:确保………::解析器(可能是Char)尝试确保向前看,但不确定它需要从什么(可能是Char)映射到boolean我最终以:确保开始(\s->s==Nothing)lookahead有意义吗?基于所有这些,我认为我的解决方案将是eof'=fmap(\x->())(确保(\s->s==Nothing)lookahead)稍后在HW中看到这个ws=pure()
确保(\s->s==Nothing)
是。或者,使用模式匹配而不是
=
(这与
Char
相同,但通常更好,因为在
Eq a=>中不施加
Eq
约束可能是不必要的)
(\s->case s of Nothing->True;->False)
)。此外,您可以尝试您的解决方案,看看它是否有效。:)
newtype Parser a = Parser { parse :: String -> Maybe (a,String) }

instance Functor Parser where
   parse (fmap f p)  s  =  [ (f a, s') | (a, s') <- parse p s ]

instance Applicative Parser where
   parse (pure a)    s  =  pure (a, s)
   parse (pf <*> pa) s  =  [ (g a, s'') | (g, s')  <- parse pf s 
                                        , (a, s'') <- parse pa s' ]

instance Alternative Parser where
   parse empty s      =  empty
   parse (l <|> r) s  =  parse l s <|> parse r s

ensure :: (a -> Bool) -> Parser a -> Parser a
parse (ensure pred p) s  =  [ (a, s') | (a, s') <- parse p s, pred a ]

lookahead :: Parser (Maybe Char)
parse lookahead []       =  pure (Nothing, [])
parse lookahead s@(c:_)  =  pure (Just c,  s )

satisfy :: (Char -> Bool) -> Parser Char
parse (satisfy p) []      =  mzero
parse (satisfy p) (x:xs)  =  [ (x, xs) | p x ]

eof :: Parser ()
parse eof s  =  [ ((), []) | null s ]  

eof' :: Parser ()
eof'  =  ???
ensure    :: (a -> Bool) -> Parser a           -> Parser a
lookahead ::                Parser (Maybe Char)
ensure  .......  ......                        :: Parser (Maybe Char)
fmap :: (  a      ->   b )                     -> Parser a        ->  Parser b
alwaysUnit nothing  =  ()
eof'  =  fmap ..... (..... ..... ......)