{-# OPTIONS -XMultiParamTypeClasses -XFlexibleInstances -XTypeSynonymInstances#-} module Monocle.Utils where import Data.Monoid class (Monoid monoid) => MStack stack monoid where pop :: stack -> (stack, monoid) push :: monoid -> stack -> stack tappend :: monoid -> stack -> stack tcombine :: (monoid -> monoid) -> stack -> stack instance (Monoid monoid) => MStack [monoid] monoid where pop s = case s of [] -> ([], mempty) x:xs -> (xs, x) push m s = m:s tappend m s = let (s', m') = pop s in push (mappend m m') s' tcombine f s = let (s', m') = pop s in tappend (f m') s' class Printable a where str :: a -> String data Wrap a = Wrap a instance Printable String where str x = if (head x) == '*' then (tail x) else x instance (Printable a, Printable b) => Printable (a, b) where str (x, y) = "(" ++ (str x) ++ ", " ++ (str y) ++ ")" instance (Show a) => Printable (Wrap a) where str (Wrap x) = show x