2016-03-30 8 views
2
module Parser where 

import   Control.Monad (MonadPlus, mplus, mzero) 
import   Tagger  (Tag, Token) 


newtype Parser a = Parser ([(Token, Tag)] -> [(a, [(Token, Tag)])]) 

parse :: Parser a -> [(Token, Tag)] -> [(a, [(Token, Tag)])] 
parse (Parser p) = p 

instance Functor Parser where 
    fmap f p = do 
     result <- p 
     return (f result) 

instance Monad Parser where 
    return a = Parser (\cs -> [(a,cs)]) 
    p >>= f = Parser (\cs -> concat [parse (f a) cs' | (a,cs') <- parse p cs]) 

instance MonadPlus Parser where 
    p `mplus` q = Parser (\cs -> parse p cs ++ parse q cs) 
    mzero = Parser (const []) 

{- 

Dies ist mein Code für meinen Parser. Anscheinend habe ich es "auf die alte Art" gemacht und kann es nicht wirklich auf die neue Art und Weise arbeiten. Kannst du mir sagen, welche Dinge ich reparieren muss, damit es funktioniert? Ich habe diesen Artikel (https://wiki.haskell.org/Functor-Applicative-Monad_Proposal) gelesen und versucht, meinen Code zu ändern, aber ich denke, dass ich hier etwas falsch mache.Haskell Parser, Monad und MonadPlus

Die Compilierung Fehler erhalte ich:

Parser.hs:56:10: 
    No instance for (Applicative Parser) 
     arising from the superclasses of an instance declaration 
    In the instance declaration for ‘Monad Parser’ 

Parser.hs:60:10: 
    No instance for (GHC.Base.Alternative Parser) 
     arising from the superclasses of an instance declaration 
    In the instance declaration for ‘MonadPlus Parser’ 

EDIT //

Der Code jetzt:

module Parser where 

import   Control.Applicative 
import   Control.Monad (mplus, mzero, liftM, ap) 
import   Tagger  (Tag, Token) 

-- type Token = String 
-- type Tag = String 

newtype Parser a = Parser ([(Token, Tag)] -> [(a, [(Token, Tag)])]) 

parse :: Parser a -> [(Token, Tag)] -> [(a, [(Token, Tag)])] 
parse (Parser p) = p 

instance Functor Parser where 
    fmap = liftM 

instance Applicative Parser where 
    pure a = Parser (\cs -> [(a,cs)]) 
    (<*>) = ap 

instance Monad Parser where 
    p >>= f = Parser (\cs -> concat [parse (f a) cs' | (a,cs') <- parse p cs]) 

instance MonadPlus Parser where --64 
    p `mplus` q = Parser (\cs -> parse p cs ++ parse q cs) 
    mzero = Parser (const []) 

instance Alternative Parser where 
    (<|>) = mplus 
    empty = mzero 

(+++) :: Parser a -> Parser a -> Parser a 
p +++ q = Parser (\cs -> case parse (p `mplus` q) cs of 
          [] -> [] 
          (x:_) -> [x]) 

Fehler:

Parser.hs:64:10: 
Not in scope: type constructor or class ‘MonadPlus’ 
+0

Sie können dem Migrationsleitfaden folgen: https: //ghc.h askell.org/trac/ghc/wiki/Migration/7.10 – zakyggaps

+0

Ich denke, dass Sie immer noch manuelle Instanzen für Applicative (die sehr einfach sein wird) und Alternative. –

+0

Danke für die Vorschläge! @zakyggaps Ich habe versucht, den Anweisungen auf Ihrem Link zu folgen, aber leider haben jetzt neue Fehler, die ich nicht sicher bin, wie ich beheben sollte. Ich muss wahrscheinlich noch etwas ändern? – katyp

Antwort

3

Sie the migration guide folgen. Es ist einfach und unkompliziert: die Definition von return-pure bewegen, fügen Sie den Textvorschlag Definition von <*> und entfernen return aus dem Monade Beispiel:

instance Functor Parser where 
    fmap = liftM 

instance Applicative Parser where 
    pure a = Parser (\cs -> [(a,cs)]) 
    (<*>) = ap 

instance Monad Parser where 
    p >>= f = Parser (\cs -> concat [parse (f a) cs' | (a,cs') <- parse p cs]) 

Für Alternative ist es vorformulierten und nichts anderes:

instance Alternative Parser where 
    (<|>) = mplus 
    empty = mzero 

Die Arbeitscode als Ganzes:

module Parser where 

import   Control.Monad 
import   Tagger  (Tag, Token) 
import   Control.Applicative 

newtype Parser a = Parser ([(Token, Tag)] -> [(a, [(Token, Tag)])]) 

parse :: Parser a -> [(Token, Tag)] -> [(a, [(Token, Tag)])] 
parse (Parser p) = p 

instance Functor Parser where 
    fmap = liftM 

instance Applicative Parser where 
    pure a = Parser (\cs -> [(a,cs)]) 
    (<*>) = ap 

instance Monad Parser where 
    p >>= f = Parser (\cs -> concat [parse (f a) cs' | (a,cs') <- parse p cs]) 

instance MonadPlus Parser where 
    p `mplus` q = Parser (\cs -> parse p cs ++ parse q cs) 
    mzero = Parser (const []) 

instance Alternative Parser where 
    (<|>) = mplus 
    empty = mzero 
+0

Also was ist "a" in der Definition von "rein"? –

+1

@PaulJohnson Entschuldigung, behoben. – zakyggaps

+0

Dieses Update gibt nur Fehler "Parser.hs: 56: 29: Nicht im Bereich: 'a'" jetzt, so scheint es ein Problem mit pure = Parser (\ cs -> [(a, cs) ]) oder so? Ich bin damit sehr neu und bin mir nicht sicher, wo die Wurzel des Problems liegt. – katyp