为什么此 haskell 代码失败
Why does this haskell code failed
首先我不是很理解报错信息,所以只能用一个模棱两可的问题标题
此代码来自第 9 频道关于 haskell 编程的第 8 章
我试图通过 GHC 运行 这段代码,然后我写了
-- Functional parsing library from chapter 13 of Programming in Haskell,
-- Graham Hutton, Cambridge University Press, 2016.
module Parsing (module Parsing, module Control.Applicative) where
import Data.Typeable
import Control.Applicative
import Data.Char
-- Basic definitions
newtype Parser a = P (String -> [(a,String)])
parse :: Parser a -> String -> [(a,String)]
parse (P p) inp = p inp
item :: Parser Char
item = P (\inp -> case inp of
[] -> []
(x:xs) -> [(x,xs)])
-- Sequencing parsers
instance Functor Parser where
-- fmap :: (a -> b) -> Parser a -> Parser b
fmap g p = P (\inp -> case parse p inp of
[] -> []
[(v,out)] -> [(g v, out)])
instance Applicative Parser where
-- pure :: a -> Parser a
pure v = P (\inp -> [(v,inp)])
-- <*> :: Parser (a -> b) -> Parser a -> Parser b
pg <*> px = P (\inp -> case parse pg inp of
[] -> []
[(g,out)] -> parse (fmap g px) out)
instance Monad Parser where
-- (>>=) :: Parser a -> (a -> Parser b) -> Parser b
p >>= f = P (\inp -> case parse p inp of
[] -> []
[(v,out)] -> parse (f v) out)
-- Making choices
instance Alternative Parser where
-- empty :: Parser a
empty = P (\inp -> [])
-- (<|>) :: Parser a -> Parser a -> Parser a
p <|> q = P (\inp -> case parse p inp of
[] -> parse q inp
[(v,out)] -> [(v,out)])
return' :: a -> Parser a
return' v = \inp -> [(v, inp)]
p' :: Parser (Char, Char)
p' = do
x <- item
item
y <- item
return' (x, y)
main = print (p' "123")
该代码包含我从给定的演示代码 Parsing.hs 复制的大量代码,以及一个与幻灯片相同的 p'
函数
运行 此代码导致错误
4.hs:63:15: error:
? Couldn't match expected type ‘[Char] -> a0’
with actual type ‘Parser (Char, Char)’
? The function ‘p'’ is applied to one argument,
but its type ‘Parser (Char, Char)’ has none
In the first argument of ‘print’, namely ‘(p' "123")’
In the expression: print (p' "123")
类型好像有问题,试过了
main = print (item "123")
也没用
然而,当我简单地删除 Parser
的定义并用上一张幻灯片中提到的定义替换它们时
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)]
main = print (item "123")
它只适用于输出 [('1',"23")]
,我在这里感到困惑。
顺便说一句,我发现评论区有个leomm问了和我一样的问题,后来他就明白了。但是我无法解决这个问题。
newtype
需要构造函数,type
不需要。如果我们想用 newtype
替换 type
,我们需要添加一个构造函数,例如 P
到我们的 Parser
类型的任何用法;为了解决 Parser
,我们实施 parse
.
从您的第二个示例代码开始,我们将得到
newtype Parser a = P (String -> [(a, String)])
parse :: Parser a -> String -> [(a,String)]
parse (P p) inp = p inp
item :: Parser Char
item = P (\inp -> case inp of
[] -> []
(x:xs) -> [(x,xs)])
main = print (parse item "12345")
现在让我们实现您的特殊解析器 p
。为了使用do
,我们实现了Monad实例。
我们在代码中添加:
instance Monad Parser where
-- (>>=) :: Parser a -> (a -> Parser b) -> Parser b
p >>= f = P (\inp -> case parse p inp of
[] -> []
[(v,out)] -> parse (f v) out)
-- return :: a -> Parser a
return v = P (\inp -> [(v, inp)])
p :: Parser (Char, Char)
p = do
x <- item
item
y <- item
return (x, y)
我们的 main
命令变为:
main = print (parse p "12345")
在我看来,ghc中的错误信息比较多,但还是要仔细阅读;在使用数据类型时也必须非常小心。
首先我不是很理解报错信息,所以只能用一个模棱两可的问题标题
此代码来自第 9 频道关于 haskell 编程的第 8 章
我试图通过 GHC 运行 这段代码,然后我写了
-- Functional parsing library from chapter 13 of Programming in Haskell,
-- Graham Hutton, Cambridge University Press, 2016.
module Parsing (module Parsing, module Control.Applicative) where
import Data.Typeable
import Control.Applicative
import Data.Char
-- Basic definitions
newtype Parser a = P (String -> [(a,String)])
parse :: Parser a -> String -> [(a,String)]
parse (P p) inp = p inp
item :: Parser Char
item = P (\inp -> case inp of
[] -> []
(x:xs) -> [(x,xs)])
-- Sequencing parsers
instance Functor Parser where
-- fmap :: (a -> b) -> Parser a -> Parser b
fmap g p = P (\inp -> case parse p inp of
[] -> []
[(v,out)] -> [(g v, out)])
instance Applicative Parser where
-- pure :: a -> Parser a
pure v = P (\inp -> [(v,inp)])
-- <*> :: Parser (a -> b) -> Parser a -> Parser b
pg <*> px = P (\inp -> case parse pg inp of
[] -> []
[(g,out)] -> parse (fmap g px) out)
instance Monad Parser where
-- (>>=) :: Parser a -> (a -> Parser b) -> Parser b
p >>= f = P (\inp -> case parse p inp of
[] -> []
[(v,out)] -> parse (f v) out)
-- Making choices
instance Alternative Parser where
-- empty :: Parser a
empty = P (\inp -> [])
-- (<|>) :: Parser a -> Parser a -> Parser a
p <|> q = P (\inp -> case parse p inp of
[] -> parse q inp
[(v,out)] -> [(v,out)])
return' :: a -> Parser a
return' v = \inp -> [(v, inp)]
p' :: Parser (Char, Char)
p' = do
x <- item
item
y <- item
return' (x, y)
main = print (p' "123")
该代码包含我从给定的演示代码 Parsing.hs 复制的大量代码,以及一个与幻灯片相同的 p'
函数
运行 此代码导致错误
4.hs:63:15: error:
? Couldn't match expected type ‘[Char] -> a0’
with actual type ‘Parser (Char, Char)’
? The function ‘p'’ is applied to one argument,
but its type ‘Parser (Char, Char)’ has none
In the first argument of ‘print’, namely ‘(p' "123")’
In the expression: print (p' "123")
类型好像有问题,试过了
main = print (item "123")
也没用
然而,当我简单地删除 Parser
的定义并用上一张幻灯片中提到的定义替换它们时
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)]
main = print (item "123")
它只适用于输出 [('1',"23")]
,我在这里感到困惑。
顺便说一句,我发现评论区有个leomm问了和我一样的问题,后来他就明白了。但是我无法解决这个问题。
newtype
需要构造函数,type
不需要。如果我们想用 newtype
替换 type
,我们需要添加一个构造函数,例如 P
到我们的 Parser
类型的任何用法;为了解决 Parser
,我们实施 parse
.
从您的第二个示例代码开始,我们将得到
newtype Parser a = P (String -> [(a, String)])
parse :: Parser a -> String -> [(a,String)]
parse (P p) inp = p inp
item :: Parser Char
item = P (\inp -> case inp of
[] -> []
(x:xs) -> [(x,xs)])
main = print (parse item "12345")
现在让我们实现您的特殊解析器 p
。为了使用do
,我们实现了Monad实例。
我们在代码中添加:
instance Monad Parser where
-- (>>=) :: Parser a -> (a -> Parser b) -> Parser b
p >>= f = P (\inp -> case parse p inp of
[] -> []
[(v,out)] -> parse (f v) out)
-- return :: a -> Parser a
return v = P (\inp -> [(v, inp)])
p :: Parser (Char, Char)
p = do
x <- item
item
y <- item
return (x, y)
我们的 main
命令变为:
main = print (parse p "12345")
在我看来,ghc中的错误信息比较多,但还是要仔细阅读;在使用数据类型时也必须非常小心。