module HOAS where
import Util
class HOAS repr where
  app :: repr (a -> b) -> repr a -> repr b
  lam :: (repr a -> repr b) -> repr (a -> b)
newtype Eval x = Eval {unEval :: x}
instance HOAS Eval where
  app (Eval f) (Eval x) = Eval (f x)
  lam f = Eval (unEval . f . Eval)
newtype HShow x = HShow {unHShow :: [String] -> String}
instance HOAS HShow where
  app (HShow f) (HShow x) = HShow (\vars -> "(" ++ f vars ++ " " ++ x vars ++ ")")
  lam f = HShow (\(v:vars) -> "(\\" ++ v ++ " -> " ++ (unHShow $ f $ HShow $ const v) vars ++ ")")
s = lam (\f -> lam (\x -> lam (\arg -> app (app f arg) (app x arg))))
main :: IO ()
main = putStrLn ((unHShow s) $ vars)