2016-03-30 20 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 []) 

{- 

Bu, ayrıştırıcım için kodum. Görünüşe göre bunu "eski yol" yaptım ve gerçekten yeni bir şekilde çalışmasını sağlayamadım. Çalışması için hangi şeyleri düzeltmem gerektiğini söyleyebilir misin? Bu makaleyi okudum (https://wiki.haskell.org/Functor-Applicative-Monad_Proposal) ve kodumu değiştirmeyi denedim ama sanırım burada yanlış bir şey yapıyorum.Haskell ayrıştırıcı, Monad ve MonadPlus

derleme hataları alıyorum: Şu anda

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’ 

DÜZENLEME //

kodu:

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]) 

Hata:

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

Taşıma kılavuzunu takip edebilirsiniz: https: //ghc.h askell.org/trac/ghc/wiki/Migration/7.10 – zakyggaps

+0

Yine de (çok kolay olacak) Uygulayıcı için manuel örneklere ve Alternatiflere ihtiyacınız olduğunu tahmin ediyorum. –

+0

Öneriler için teşekkürler! @zakyggaps Bağlantınızdaki talimatları izlemeye çalıştım ama ne yazık ki şimdi nasıl düzeltmem gerektiğini bilmediğim yeni hatalar var. Muhtemelen bir şeyi değiştirmek zorundayım. – katyp

cevap

3

Sen the migration guide takip edebilir. Çok basit ve anlaşılır açıklanmıştır:, pure için return tanımını hareket <*> ait demirbaş tanımını ekleyebilir ve tek hücreli canlı örneğinden return kaldırın: Alternative için

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]) 

Başka Demirbaş ve hiçbir şey:

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

Bir bütün olarak çalışma kodu:

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

Peki "saf" tanımında "a" nedir? –

+1

@PaulJohnson Üzgünüz, düzeltildi. – zakyggaps

+0

Bu düzeltme yalnızca hata veriyor "Parser.hs: 56: 29: Kapsamda değil: 'a'" şimdi, saf bir şekilde bir sorun var gibi görünüyor = Ayrıştırıcı (\ cs -> [(a, cs) ]) ya da başka birşey? Bu konuda çok yeniyim ve sorunun kökünün nerede olduğundan emin değilim. – katyp