Haskell解析器类方法签名错误求助:MonadZero相关问题
Haskell单子解析器编译错误修复求助
我正按照一篇Haskell单子解析的经典论文实现解析器,已移除NoImplicitPrelude编译指示,当前使用Prelude中的Monad类型类。以下是我的实现代码:
-- {-# LANGUAGE NoImplicitPrelude #-} module MonadicParsingInHaskell () where import Data.Char import GHC.Types import GHC.Base (Monad) import GHC.Base hiding (MonadPlus, (++), many) import Data.List (concat) newtype Parser a = Parser (String -> [(a,String)]) item :: Parser Char item = Parser (\cs -> case cs of "" -> [] (c:cs) -> [(c,cs)]) instance Monad Parser where return a = Parser (\cs -> [(a,cs)]) p >>= f = Parser (\cs -> concat [parse (f a) cs' | (a,cs') <- parse p cs]) p :: Parser (Char,Char) p = do {c <- item; item; d <- item; return (c,d)} class Monad m => MonadZero m where zero :: m a instance MonadZero => MonadPlus m where zero :: m a instance MonadZero => Parser where zero = Parser (\cs -> []) class MonadZero m => MonadPlus m where (++) :: m a -> m a -> m a instance MonadZero Parser where zero = Parser (\cs -> []) instance MonadZero Parser where zero = Parser (\cs -> []) parse :: Parser a -> String -> [(a, String)] parse (Parser p) = p many :: Parser a -> Parser [a] many p = many1 p +++ return [] many' :: Parser a -> Parser [a] many' p = many p +++ return [] (+++) :: Parser a -> Parser a -> Parser a p +++ q = Parser (\cs -> case parse (p MonadicParsinginHaskell.++ q) cs of [] -> [] (x:xs) -> [x]) instance Monad Parser where return a = Parser (\cs -> [(a,cs)]) p >>= f = Parser (\cs -> concat [parse (f a) cs' | (a, cs') <- parse p cs]) sat :: (Char -> Bool) -> Parser Char sat p = do {c <- item; if p c then return c else zero} char :: Char -> Parser Char char c = sat (c ==) string :: String -> Parser String string "" = return "" string (c:cs) = do {char c; string cs; return (c:cs)} many1 :: Parser a -> Parser [a] many1 p = do {a <- p; as <- many p; return (a:as)} sepby :: Parser a -> Parser b -> Parser [a] p `sepby` sep = (p `sepby1` sep) +++ return [] sepby1 :: Parser a -> Parser b -> Parser [a] p `sepby1` sep = do a <-p as <- many (do {sep; p}) return (a:as) chainl :: Parser a -> Parser (a -> a -> a) -> a -> Parser a chainl p op a = (p `chainl1` op) +++ return a chainl1 :: Parser a -> Parser (a -> a -> a) -> Parser a p `chainl1` op = do {a <- p; rest a} where rest a = (do f <- op b <- p rest (f a b)) +++ return a space :: Parser String space = many (sat isSpace) token :: Parser a -> Parser a token p = do a <- p; space; return a symb :: String -> Parser String symb cs = token (string cs) apply :: Parser a -> String -> [(a,String)] apply p = parse (do {space; p}) expr :: Parser Int expr = term `chainl1` addop addop :: Parser (Int -> Int -> Int) addop = do {symb "+"; return (+)} +++ do {symb "-"; return (-)} mulop :: Parser (Int -> Int -> Int) mulop = do {symb "*"; return (*)} +++ do {symb "/"; return div} term :: Parser Int term = factor `chainl1` mulop factor :: Parser Int factor = digit +++ do {symb "("; n <- expr; symb ")"; return n} digit :: Parser Int digit = do {x <- token (sat isDigit); return (ord x - ord '0')}
编译时抛出错误:
The class method signature lacks an accompanying binding. Move the class method site signature to the declaration site of zero.
单独定义MonadZero类型类时没有问题:
class Monad m => MonadZero m where zero :: m a
我无法修正MonadZero => Parser相关的实例声明问题,特此求助。
内容的提问来源于stack exchange,提问作者Luke McCartney
相关产品推荐
相关产品推荐

