2013-08-18 28 views
5

Parsec'i öğrenmeye çalışıyorum ve basit bir e-posta adresini ayrıştırmaya çalışıyorum. Aşağıdaki kodu denedim. Beklediğim çıktı, tüm e-posta adresi bir dizge. Ama kodu çalıştırdığımda, sadece ".com" aldım. Bir şey olabilir mi, lütfen bana neler olduğunu anlatın?Haskell Parsec yazıyor

{-# LANGUAGE NoMonomorphismRestriction #-} 

import Text.Parsec 
import Control.Applicative hiding ((<|>)) 

email = many1 alphaNum 
    *> char '@' 
    *> many1 alphaNum 
    *> string ".com" 

emailstr = parse email "" "[email protected]" 

cevap

12

*> için tür imzası o ikinci ayrıştırıcı sonucunu verir ve ilk ayrıştırıcı sonucunu uzağa atar diyor. Böylece, email, yalnızca dizideki son ayrıştırıcıdan sonucu döndürür.

Ne muhtemelen istediğiniz Bu dört ayrıştırıcılar çalışır ve stitch bir argüman olarak her sonucunu geçer daha

email = 
    stitch 
    <$> many1 alphaNum 
    <*> char '@' 
    <*> many1 alphaNum 
    <*> string ".com" 

gibi bir şeydir. Eğer stitch için uygun bir uygulama yazarsanız:

stitch a b c d = a ++ [b] ++ C++ d 

o zaman dize geri dönmeliyim. Bu noktada, aynı zamanda bir veri yapısı falan ayrı alanlara kullanıcı adı ve alan koyabilirsiniz

Uyarı:

data Email = Email {username, domain :: String} 

email = 
    Email 
    <$> many1 alphaNum 
    <* char '@' 
    <*> ((++) <$> many1 alphaNum <*> string ".com") 

Şimdi ayrıştırıcı sadece düz bir dize yerine bir Email yapısını döndürür. Bu sizin peşinde olduğunuz şey olmayabilir, ancak daha sofistike bir ayrıştırıcı yazmayı gösterir.

Tüm bunlar, genel olarak iyi stil kabul edilen Parsec'e Applicative arabirimini kullanıyor.

email = do 
    a <- many1 alphaNum 
    b <- char '@' 
    c <- many1 alphaNum 
    d <- string ".com" 
    return (a ++ [b] ++ C++ d) 
+0

bu deyimsel Çözüme ulaşmanın yolu, söz konusu görev mi: parsekten kullanmak diğer yolu Monad arayüzüdür? Kodu üretimde hiçbir yerde kullanmam. Ben sadece parsec'i öğrenmeye çalışıyorum. – Jay

+0

Her iki yöntem de deyimseldir – nponeccop