Parsing 应用解析器陷入无限循环
我正在尝试实现自己的应用程序解析器,下面是我使用的代码:Parsing 应用解析器陷入无限循环,parsing,haskell,infinite-loop,lazy-evaluation,alternative-functor,Parsing,Haskell,Infinite Loop,Lazy Evaluation,Alternative Functor,我正在尝试实现自己的应用程序解析器,下面是我使用的代码: {-# LANGUAGE ApplicativeDo, LambdaCase #-} module Parser where -- Implementation of an Applicative Parser import Data.Char import Control.Applicative (some, many, empty, (<*>), (<$>), (<|>), Alternati
{-# LANGUAGE ApplicativeDo, LambdaCase #-}
module Parser where
-- Implementation of an Applicative Parser
import Data.Char
import Control.Applicative (some, many, empty, (<*>), (<$>), (<|>), Alternative)
data Parser a = Parser { runParser :: String -> [(a, String)] }
instance Functor Parser where
-- fmap :: (a -> b) -> (Parser a -> Parser b)
fmap f (Parser p) = Parser (\s -> [(f a, s') | (a,s') <- p s])
instance Applicative Parser where
-- pure :: a -> Parser a
-- <*> :: Parser (a -> b) -> Parser a -> Parser b
pure x = Parser $ \s -> [(x, s)]
(Parser pf) <*> (Parser p) = Parser $ \s ->
[(f a, s'') | (f, s') <- pf s, (a, s'') <- p s']
instance Alternative Parser where
-- empty :: Parser a
-- <|> :: Parser a -> Parser a -> Parser a
empty = Parser $ \_s -> []
(Parser p1) <|> (Parser p2) = Parser $ \s ->
case p1 s of [] -> p2 s
xs -> xs
char :: Char -> Parser Char
char c = Parser $ \case (c':cs) | c == c' -> [(c,cs)] ; _ -> []
main = print $ runParser (some $ char 'A') "AAA"
{-#语言应用程序,LambdaCase}
模块解析器在哪里
--应用解析器的实现
导入数据.Char
import Control.Applicative(一些、许多、空、()、()、可选)
数据解析器a=解析器{runParser::String->[(a,String)]}
实例函子解析器,其中
--fmap::(a->b)->(解析器a->解析器b)
fmap f(Parser p)=解析器(\s->[(fa,s')|(a,s')解析器a
--::解析器(a->b)->解析器a->解析器b
纯x=解析器$\s->[(x,s)]
(解析器pf)(解析器p)=解析器$\s->
[(fa,s'')|(f,s')事实“星”:在您的()
实现中:
…我们必须进行足够的计算,以知道这两个解析器实际上都是解析器
构造函数对某个对象的应用,然后才能转到等号的右侧
事实“管道延迟”:在此实现中:
Parser p1 <|> Parser p2 = ...
p1 <|> p2 = Parser $ ...
让我们看一下您的第一个实现,我们知道“pipe strict”事实。我们想知道some_v
是否是解析器
对某事物的应用。由于事实“star”,因此我们必须知道是否纯(:)
,v
和some_v纯[]
是解析器对某事物的应用程序。要知道最后一个,我们必须知道是否是某些
和纯[]
是Parser
对某物的应用。哎呀!我们刚刚演示了要知道some\u v
是否是Parser
对某物的应用,我们需要知道some\u v
是否是Parser
对某物的应用——一个无限循环
另一方面,在您的第二个实现中,为了检查some_v
是否是解析器
,我们仍然必须检查pure(:)
,v
,以及some_v pure[]
,但由于“管道惰性”这一事实,这就是我们需要检查的全部——我们可以确信some_v pure[]
是一个解析器
,它没有首先递归地检查某些
和纯[]
是什么
(接下来,您将了解newtype
——当从data
更改为newtype
时,您将再次感到困惑,因为这两种实现都可以工作!)事实“星”:在()
的实现中:
…我们必须进行足够的计算,以知道这两个解析器实际上都是解析器
构造函数对某个对象的应用,然后才能转到等号的右侧
事实“管道延迟”:在此实现中:
Parser p1 <|> Parser p2 = ...
p1 <|> p2 = Parser $ ...
让我们看一下您的第一个实现,我们知道“pipe strict”事实。我们想知道some_v
是否是解析器
对某事物的应用。由于事实“star”,因此我们必须知道是否纯(:)
,v
和some_v纯[]
是解析器对某事物的应用程序。要知道最后一个,我们必须知道是否是某些
和纯[]
是Parser
对某物的应用。哎呀!我们刚刚演示了要知道some\u v
是否是Parser
对某物的应用,我们需要知道some\u v
是否是Parser
对某物的应用——一个无限循环
另一方面,在您的第二个实现中,为了检查some_v
是否是解析器
,我们仍然必须检查pure(:)
,v
,以及some_v pure[]
,但由于“管道惰性”这一事实,这就是我们需要检查的全部——我们可以确信some_v pure[]
是一个解析器
,它没有首先递归地检查某些
和纯[]
是什么
(接下来,您将了解newtype
——当从data
更改为newtype
时,您将再次感到困惑,因为这两种实现都可以工作!)此外,如果您使用的是列表而不是Maybe,我希望您的
实现能够无条件地调用这两个解析器,并将它们的结果与(++)
;(Parser p)(Parser q)=Parser$(\s->ps++qs)结合起来
@amalloy:你是对的,但不管怎样,它都会陷入同一个循环。@ShouYa这不仅仅是“这两种不同的方法在概念上是相同的”,而是“你已经粘贴了完全相同的代码两次,并且问为什么它只工作一次”。@amalloy oops我的错。修复:)另外,如果您使用的是列表而不是Maybe,我希望您的
实现能够无条件地调用这两个解析器,并将它们的结果与(++)
;(Parser p)(Parser q)=Parser$(\s->p s++q s)
@amalloy:您是对的,但无论如何它都会陷入同一个循环。@ShouYa不仅仅是“这两种不同的方法在概念上是相同的”,但是“你已经粘贴了两次完全相同的代码,并且问为什么它只工作一次”。@amalloy oops我的错。修复:)
some v = some_v where
some_v = pure (:) <*> v <*> (some_v <|> pure [])