{-# LANGUAGE TypeOperators #-} import Prelude hiding (foldl) infixr 1 :-> newtype a :-> b = S {unS :: a -> b} infixl 9 # class Fun f where lam :: (a -> b) -> f a b (#) :: f a b -> (a -> b) instance Fun (->) where lam = id (#) = ($) instance Fun (:->) where lam = S (#) = \f x -> unS f $! x foldl :: (Fun i, Fun j) => i b (j a b) -> i b ([a] :-> b) foldl = lam $ \f -> lam $ \e -> lam $ \l -> case l of [] -> e x : xs -> foldl # f # (f # e # x) # xs lplus :: Int -> Int -> Int lplus = (+) splus :: Int :-> Int :-> Int splus = lam $ \m -> lam $ \n -> ((+) $! m) $! n