import Data.Char data Natural = Zero | Succ Natural deriving ( Show , Eq ) unu = Succ Zero doi = Succ unu addNat Zero n = n addNat (Succ m) n = Succ (addNat m n) data Triple a b c = T a b c deriving (Show, Eq) first (T x _ _) = x second (T _ x _) = x third (T _ _ x) = x type TripleInt = Triple Int Int Int --[Char] -> (ParseRes Expr, [Char]) type Parser a b = [a] -> (ParseRes b, [a]) data ParseRes b = Failed | Parsed b deriving (Show, Eq) fromRes Failed = undefined fromRes (Parsed x) = x data Expr = Number Integer | Op Expr Char Expr deriving (Show, Eq) makeTokenParserF :: (a -> Bool) -> Parser a a makeTokenParserF f = \i@(h:t) -> if f h then (Parsed h, t) else (Failed, i) digitParser = makeTokenParserF isDigit operatorParser = makeTokenParserF (\c -> elem c ['+', '*']) -- take 4 $ map (fromRes . fst) $ iterate (digitParser . snd) $ digitParser "1234" (>.>) p1 p2 = \input -> let (res1, rem1) = p1 input in case res1 of Failed -> (Failed, input) Parsed r1 -> case p2 rem1 of (Failed, _) -> (Failed, input) (Parsed r2, rem2) -> (Parsed (r1, r2), rem2) -- digitParser >.> digitParser --> parser pt 2 cifre (>=>) parser process input = case res of Failed -> (Failed, rem) Parsed r -> (Parsed (process r), rem) where (res, rem) = parser input secv parser input | res == Failed = (Failed, input) | resMore == Failed = let Parsed r = res in (Parsed [r], rem) | otherwise = (parser >.> secv parser) >=> (\(resParser, resSecv) -> resParser : resSecv) $ input where (res, rem) = parser input (resMore, remMore) = parser rem (>*>) parser process = secv parser >=> process -- (digitParser >*> (fromInteger . read)) $ "1234+" numberParser = digitParser >*> (fromInteger . read) >=> Number (>|>) :: Parser a b -> Parser a b -> Parser a b (>|>) p1 p2 input = case (res1, res2) of (Failed, Failed) -> (Failed, input) (Parsed r, _) -> r1 (_, Parsed r) -> r2 where r1@(res1, rem1) = p1 input r2@(res2, rem2) = p2 input {- operandParser = ((tokenParser '(' >.> exprParser >.> tokenParser ')') >=> (\((openPar, e), closedPar) -> e)) >|> numberParser -} operandParser = ((tokenParser '(' >.> exprParser >.> tokenParser ')') >=> (\((_, e), _) -> e)) >|> numberParser exprParser = ((operandParser >.> operatorParser >.> operandParser) >=> (\((e1, op), e2)-> Op e1 op e2 )) >|> numberParser tokenParser s = makeTokenParserF (==s) compute (Number x) = x compute (Op e1 '+' e2) = compute e1 + compute e2 compute (Op e1 '*' e2) = compute e1 * compute e2