Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Parsing Haskell中带do构造的简单解析_Parsing_Haskell_Functional Programming - Fatal编程技术网

Parsing Haskell中带do构造的简单解析

Parsing Haskell中带do构造的简单解析,parsing,haskell,functional-programming,Parsing,Haskell,Functional Programming,我正在尝试编写一个简单的解析器,因此所有声明都列在下图中,但是当我尝试编译这个模块时,它失败了。 我正在遵循此来源提供的教程-> 特别是Erik Meijer博士的这段视频() 问题是,我认为“do”构造能够以降序方式“串联”来自前一个函数的输出,但这个p函数的工作方式对我来说似乎很神奇。什么是正确的实现 -- Generic Parser. type Parser a = String -> [(a, String)] -- A simple Parser that captures

我正在尝试编写一个简单的解析器,因此所有声明都列在下图中,但是当我尝试编译这个模块时,它失败了。 我正在遵循此来源提供的教程-> 特别是Erik Meijer博士的这段视频()

问题是,我认为“do”构造能够以降序方式“串联”来自前一个函数的输出,但这个p函数的工作方式对我来说似乎很神奇。什么是正确的实现

-- Generic Parser.
type Parser a = String -> [(a, String)]

-- A simple Parser that captures the first char of the string, puts it in
-- the first position of the couple and then puts the rest of the string into
-- the second place of the couple inside the singleton list.
item :: Parser Char
item = \inp -> case inp of
    [] -> []
(x:xs) -> [(x, xs)]

-- Simple parser that always fails.    
failure :: Parser a
failure = \inp -> []

-- Returns the type of the parser without operating on the input.
return1 :: a -> Parser a
return1 v = \inp -> [(v, inp)]

-- Explicit call to parse.
parse :: Parser a -> String -> [(a, String)]
parse p inp = p inp

-- Some kind of "or" operator that if the first parser fails (returning an empty list) it
-- parses the second parser.
(+++) :: Parser a -> Parser a -> Parser a
p +++ q = \inp -> case p inp of
    [] -> parse q inp
    [(v, out)] -> [(v, out)]

-- The function within I'm having troubles.
p :: Parser (Char,Char)
p = do
    x <- item
    item
    y <- item
    return1 (x, y)
——泛型解析器。
类型解析器a=String->[(a,String)]
--一个简单的解析器捕获字符串的第一个字符,并将其放入
--第一个位置的夫妇,然后把其余的字符串进入
--这对夫妇在独生子女名单中的第二名。
项::解析器字符
item=\inp->case inp of
[] -> []
(x:xs)->[(x,xs)]
--总是失败的简单解析器。
失败::分析器a
失败=\inp->[]
--返回解析器的类型,而不对输入进行操作。
return1::a->Parser a
return1 v=\inp->[(v,inp)]
--显式调用解析。
parse::Parser a->String->[(a,String)]
解析p inp=p inp
--某种类型的“或”运算符,如果第一个解析器失败(返回空列表),它将
--解析第二个解析器。
(+++)::解析器a->解析器a->解析器a
p+++q=\inp->
[]->parse q inp
[(v,out)]->[(v,out)]
--我内心的功能有问题。
解析器(Char,Char)
p=do

x您的
解析器
只是函数的类型同义词。您所看到的友好解析器都是自己的适当类型,带有
Functor
Applicative
实例,以及(在大多数情况下)
Alternative
Monad
MonadPlus
实例。您可能需要类似以下(未经测试,从未编译)版本的内容

import Control.Monad(ap,liftM)
进口控制。适用(可选(..)
newtype解析器a=解析器
{runParser::String->[(a,String)]}
实例函子解析器,其中
fmap=liftM
实例应用程序解析器,其中
纯v=解析器$\inp->[(v,inp)]
()=ap
实例Monad解析器,其中
--不需要下一行
--GHC最新版本
--返回=纯
解析器m>>=f=Parser$\s->

[(r,s'')|(x,s')您的
解析器
只是函数的类型同义词。您所看到的友好解析器都是它们自己的适当类型,带有
Functor
Applicative
实例,以及(在大多数情况下)
Alternative
Monad
MonadPlus
实例。您可能需要类似以下(未测试,从未编译)版本的内容

import Control.Monad(ap,liftM)
进口控制。适用(可选(..)
newtype解析器a=解析器
{runParser::String->[(a,String)]}
实例函子解析器,其中
fmap=liftM
实例应用程序解析器,其中
纯v=解析器$\inp->[(v,inp)]
()=ap
实例Monad解析器,其中
--不需要下一行
--GHC最新版本
--返回=纯
解析器m>>=f=Parser$\s->

[(r,s'')|(x,s')您的
解析器的
Monad
实例在哪里?您的
p
正在使用
(>)String
monad,不是任何类型的
Parser
monad。你需要将
Parser
a
newtype
,然后为它编写
monad
实例,然后才能使用
do
。@n.m.对不起,我编辑了这个问题。我不明白为什么会被否决。应该替换图像,我同意--但至少这个问题显示了一些努力,不像学习哈斯克尔的人所做的其他许多努力。我认为埃里克·梅杰在他的演讲中玩弄得又快又松。你不能真的用一元解析的方式将
Parser
作为
Monad
的一个实例。问题是,
String->
Monad(因此do表示法有效),但它是一个错误的实例,并且生成了所有错误的类型。请尝试使用显式的
bind
而不是
do
重写此函数。或者,您可以将
Parser
包装成如下的新类型
newtype Parser a=Parser{unparser::String->[(a,String)]
并为此定义一个Monad实例…但这对于第一节Monad课程来说可能太多了…您的
解析器的
Monad
实例在哪里?您的
p
正在使用
(>)String
monad,不是任何类型的
Parser
monad。你需要将
Parser
a
newtype
,然后为它编写
monad
实例,然后才能使用
do
。@n.m.对不起,我编辑了这个问题。我不明白为什么会被否决。应该替换图像,我同意--但至少这个问题显示了一些努力,不像学习哈斯克尔的人所做的其他许多努力。我认为埃里克·梅杰在他的演讲中玩弄得又快又松。你不能真的用一元解析的方式将
Parser
作为
Monad
的一个实例。问题是,
String->
Monad(因此do表示法有效),但它是一个错误的实例,并且生成了所有错误的类型。请尝试使用显式的
bind
而不是
do
重写此函数。或者,您可以将
Parser
包装成如下的新类型
newtype Parser a=Parser{unparser::String->[(a,String)]
并为此定义一个Monad实例……但这对于第一节Monad课程来说可能太多了。。。
import Control.Monad (ap, liftM)
import Control.Applicative (Alternative (..))

newtype Parser a = Parser
  { runParser :: String -> [(a, String)] }

instance Functor Parser where
  fmap = liftM

instance Applicative Parser where
  pure v = Parser $ \inp -> [(v, inp)]
  (<*>) = ap

instance Monad Parser where
  -- The next line isn't required for
  -- recent GHC versions
  -- return = pure

  Parser m >>= f = Parser $ \s ->
    [(r, s'') | (x, s') <- m s
              , (r, s'') <- runParser (f r) s']

(+++) :: Parser a -> Parser a -> Parser a
p +++ q = Parser $ \inp -> case runParser p inp of
  [] -> runParser q inp
  [(v, out)] -> [(v, out)]

failure :: Parser a
failure = Parser $ \inp -> []

instance Alternative Parser where
  (<|>) = (+++)
  empty = failure

instance MonadPlus Parser