ein Datentyp data CI = CI Int Int
, die eine komplexe Zahl gegeben, möchte ich einen Parser für CI bauen, die "a"
zu CI a 0
und "(a,b)"
zu CI a b
umwandeln kann. Zum Beispiel möchte ich eine Funktion parseCI
wie runParser parseCI "(1,2)"
gibt den Wert [(CI 1 2, "")]
(im Idealfall, aber etwas ähnliches ist in Ordnung). Ich möchte CI auch eine Instanz von read
machen.Parsing eine komplexe Zahl von Scratch
Ich möchte dies mit Funktionen und Definitionen aus dem unten stehenden Code tun (im Grunde ohne etwas fortgeschrittenes, wie Parsec), aber ich bin mir nicht sicher, wo ich anfangen soll. Irgendein Startcode, um mich auf die richtige Spur und/oder einen Hinweis zu setzen, wäre hilfreich. Ich suche keine vollständige Antwort, da ich das selbst herausfinden möchte.
module Parser where
import Control.Applicative
import Control.Monad
newtype Parser a = Parser { runParser :: String -> [(a,String)] }
satisfy :: (Char -> Bool) -> Parser Char
satisfy f = Parser $ \s -> case s of
[] -> []
a:as -> [(a,as) | f a]
char :: Char -> Parser Char
char = satisfy . (==)
string :: String -> Parser String
string str = Parser $ \s -> [(t,u) | let (t,u) = splitAt (length str) s, str == t]
instance Functor Parser where
fmap f p = Parser $ \s ->
[ (f a,t)
| (a,t) <- runParser p s
]
instance Applicative Parser where
pure a = Parser $ \s -> [(a,s)]
af <*> aa = Parser $ \s ->
[ (f a,u)
| (f,t) <- runParser af s
, (a,u) <- runParser aa t
]
instance Alternative Parser where
empty = Parser $ \s -> []
p1 <|> p2 = Parser $ (++) <$> runParser p1 <*> runParser p2`
instance Monad Parser where
return = pure
ma >>= f = Parser $ \s ->
[ (b,u)
| (a,t) <- runParser ma s
, (b,u) <- runParser (f a) t
]
instance MonadPlus Parser where
mzero = empty
mplus = (<|>)
Technisch gesehen, das ist eine Gauß-Nummer/nitpick. – ThreeFx