#define DEMO(p,i) demo "p" i p
module Text.ParserCombinators.UU.Idioms where
import Text.ParserCombinators.UU
import Text.ParserCombinators.UU.BasicInstances hiding (Parser)
import Text.ParserCombinators.UU.Utils
import Text.ParserCombinators.UU.Demo.Examples hiding (show_demos)
import qualified Data.ListLike as LL
import Control.Applicative
data IF = IF
data THEN = THEN
data ELSE = ELSE
data FI = FI
data OR = OR
data String' = String' {fromStr :: String}
data Ii = Ii
iI ::Idiomatic i (a -> a) g => g
iI = idiomatic (pure id)
class Idiomatic st f g | g -> f st where
idiomatic :: P st f -> g
instance Idiomatic st x (Ii -> P st x) where
idiomatic ix Ii = ix
instance Idiomatic st f g => Idiomatic st (a -> f) (P st a -> g) where
idiomatic isf is = idiomatic (isf <*> is)
instance Idiomatic st f g => Idiomatic st ((a -> b) -> f) ((a -> b) -> g) where
idiomatic isf f = idiomatic (isf <*> (pure f))
instance (Idiomatic (Str Char state loc) f g, IsLocationUpdatedBy loc Char, LL.ListLike state Char)
=> Idiomatic (Str Char state loc) f (String -> g) where
idiomatic isf str = idiomatic (isf <* lexeme (pToken str))
instance (Idiomatic (Str Char state loc) f g, IsLocationUpdatedBy loc Char, LL.ListLike state Char)
=> Idiomatic (Str Char state loc) f (Char -> g) where
idiomatic isf c = idiomatic (isf <* lexeme (pSym c))
instance Idiomatic st f g => Idiomatic st (a -> f) (IF -> Bool -> THEN -> P st a -> ELSE -> P st a -> FI -> g) where
idiomatic isf IF b THEN t ELSE e FI = idiomatic (isf <*> (if b then t else e))
pNat :: Parser Int
pNat = pNatural
show_demos :: IO ()
show_demos = demo "(+) <$> (iI (+) '(' pNat \"plus\" IF True THEN pNat ELSE pNat FI ')' Ii) <* lexeme (pSym '+') <*> pNat)" "(2 plus 3) + 8"
((+) <$> (iI (+) '(' pNat "plus" IF True THEN pNat ELSE pNat FI ')' Ii) <* lexeme (pSym '+') <*> pNat)