为什么在这个解析器序列中出现类型错误(Erik Meijer第8讲)? [英] Why am I getting a type error in this sequence of parsers (lecture 8 by Erik Meijer)?
问题描述
我正在观看Erik Meijer的演讲系列函数式编程基础知识(Graham Hutton的幻灯片)。
在第8讲(关于功能解析器)中,在定义 然而,当我尝试在GHCi中加载时,以下类型的错误,我没有想到和不明白: 我做错了什么? 问题在于 我可能是错的,但看起来像 如果你使用这个定义,你会看到 如果你想使用 博客文章如何使用 I'm in the process of watching the Functional Programming Fundamentals lecture series by Erik Meijer (with slides by Graham Hutton). In lecture 8 (on functional parsers), after defining the However, when I try to load this in GHCi, I get the following type error, which I didn't expect and don't understand: What am I doing wrong? The problem is that the do notation in your definition of I could be wrong, but it looks like If you use this definition you'll see that If you want to use Here is a good blog post on how to define a parser monad instance using 这篇关于为什么在这个解析器序列中出现类型错误(Erik Meijer第8讲)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! Parser a
类型,引入了一些解析原语(包括 项目
和 return
,我命名为 return'
),Erik给出了 <$ c $>使用do语法可以将他的解析器组合成一个序列c> type Parser a = String - > [(a,String)]
item :: Parser Char
item = \inp - > case $ in
[] - > []
(x:xs) - > [(x,xs)]
return':: a - >解析器
返回'v = \inp - > [(v,inp)]
p :: Parser(Char,Char)
p = do x < - item
item
y < - item
return'(x,y)
pre $ 无法匹配类型'[(Char ,字符串)]'与'Char'
期待的类型:字符串 - > [((Char,Char),String)]
实际类型:Parser([(Char,String)],[(Char,String)]]
在'do'返回'(x,y)
在表达式中:
do {x< - item;
项目;
y< - item;
return'(x,y)}
失败,模块加载:无。
p
定义中的符号不使用您希望它使用的monad。
p
正在使用Reader monad的一个版本。
x
和 y
不是 Char
值,但是类型为 [(Char,String)]
:
import Debug.Trace
p :: Parser(Char,Char)
p = do x < - item
y< - item
let foo = trace(x =++ show x)'a'
bar = trace(y =++ show y)'b'
return'(foo ,bar)
test = pqwe
do
表示法,您应该创建 newtype
或 data
声明为解析器
,所以你可以定义e如何运行绑定操作符(>> =),例如:
newtype Parser a = Parser {parse :: String - > ; [(a,String)]}
实例Monad Parser其中
return = Parser。返回'
(>> =)= ...
newtype
定义解析器monad实例:(链接) Parser a
type, introducing a few parsing primitives (including item
and return
, which I named return'
), Erik gives a simple example of how his parsers can be combined in a sequence, using the do syntax:type Parser a = String -> [(a,String)]
item :: Parser Char
item = \inp -> case inp of
[] -> []
(x:xs) -> [(x,xs)]
return' :: a -> Parser a
return' v = \inp -> [(v,inp)]
p :: Parser (Char,Char)
p = do x <- item
item
y <- item
return' (x,y)
Couldn't match type ‘[(Char, String)]’ with ‘Char’
Expected type: String -> [((Char, Char), String)]
Actual type: Parser ([(Char, String)], [(Char, String)])
In a stmt of a 'do' block: return' (x, y)
In the expression:
do { x <- item;
item;
y <- item;
return' (x, y) }
Failed, modules loaded: none.
p
is not using the monad you want it to use.p
is using a version of the Reader monad.x
and y
are not Char
values but have type [(Char,String)]
:import Debug.Trace
p :: Parser (Char,Char)
p = do x <- item
y <- item
let foo = trace ("x = " ++ show x) 'a'
bar = trace ("y = " ++ show y) 'b'
return' (foo,bar)
test = p "qwe"
do
notation, you should create a newtype
or data
declaration for Parser
so you can define how the bind operator (>>=) works, e.g.:newtype Parser a = Parser { parse :: String -> [ (a,String) ] }
instance Monad Parser where
return = Parser . return'
(>>=) = ...
newtype
: (link)