Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.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
Haskell类型错误_Haskell_Types - Fatal编程技术网

Haskell类型错误

Haskell类型错误,haskell,types,Haskell,Types,考虑以下Haskell代码: type Parser a = String -> [(a, String)] item :: Parser Char item = \ inp -> case inp of [] -> [] (x:xs) -> [(x, xs)] ret :: a -> Parser a ret v = \ inp -> [(v, inp)] parse ::

考虑以下Haskell代码:

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

 item :: Parser Char
 item = \ inp -> case inp of
                 [] -> []
                 (x:xs) -> [(x, xs)]

 ret :: a -> Parser a
 ret v = \ inp -> [(v, inp)]

 parse :: Parser a -> String -> [(a, String)]
 parse p inp = p inp

 pseq :: Parser (Char, Char)
 pseq = do x <- item
           item
           y <- item
           ret (x, y)

 ac = parse pseq "abcdef"
并且,当我删除“pseq”的类型声明时,会收到以下错误消息:

Type error in explicitly typed binding
*** Term           : pseq
*** Type           : [Char] -> [(([(Char,[Char])],[(Char,[Char])]),[Char])]
*** Does not match : Parser (Char,Char)
Unresolved top-level overloading
*** Binding             : pseq
*** Outstanding context : Monad ((->) [Char])

问题是您试图使用
do
-表示法来表示
解析器
,但它并不完全是
单子。这有点像,因为
r->
有一个
Monad
实例,但这使得
->
右侧的类型成为
Monad
的“元素”类型,这里您希望元素类型是
[(a,String)]
中的
a
。您需要将
解析器
定义为一个
新类型
,并为它编写一个自定义的
Monad
实例(或者使用现有的Monad/transformer,如
ListT
StateT
)来编写它。

将解析器变成Monad很容易,而且我认为使用ListT或StateT在这里可能有点过头了

newtype Parser a = Parser (String -> [(a, String)])
    -- make this a distinct type
    -- now the function is "wrapped", though at no run-time cost

instance Monad Parser where
    return = ret    -- you already had it defined
    (>>=) = bind    -- added below
    -- this instance makes Parser a Moand, and lets it work with do notation

item :: Parser Char
item = Parser $ \ inp -> case inp of
                         [] -> []
                         (x:xs) -> [(x, xs)]
    -- need to "wrap" up the function as a Parser value

ret :: a -> Parser a
ret v = Parser $ \ inp -> [(v, inp)]
    -- need to "wrap" up the function as a Parser value

bind :: Parser a -> (a -> Parser b) -> Parser b
bind p f = Parser $ \ s -> case parse p s of
                           [] -> []
                           [(a, s')] -> parse (f a) s'
    -- the only function you were missing
    -- it is worth making sure you understand how it works

parse :: Parser a -> String -> [(a, String)]
parse (Parser p) inp = p inp
    -- needs to "unwrap" the newtype here

pseq :: Parser (Char, Char)
pseq = do x <- item
          item
          y <- item
          ret (x, y)

ac = parse pseq "abcdef"
    -- you probably meant pseq here, not seq
newtype解析器a=解析器(字符串->[(a,字符串)])
--让这成为一个独特的类型
--现在该函数已“包装”,但没有运行时成本
实例Monad解析器,其中
return=ret——您已经定义了它
(>>=)=绑定--添加到下面
--这个实例使解析器成为Moand,并允许它使用do符号
项::解析器字符
item=Parser$\inp->case inp of
[] -> []
(x:xs)->[(x,xs)]
--需要将函数“包装”为解析器值
ret::a->Parser a
ret v=Parser$\inp->[(v,inp)]
--需要将函数“包装”为解析器值
绑定::解析器a->(a->解析器b)->解析器b
bind p f=Parser$\s->case parse p s of
[] -> []
[(a,s')]->解析(f a)s'
--你唯一缺少的功能
--确保您了解它的工作原理是值得的
parse::Parser a->String->[(a,String)]
parse(Parser p)inp=p inp
--需要在此处“展开”新类型
pseq::解析器(Char,Char)
pseq=dox