{-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE CPP #-} import Data.Function.Polyvariadic import Data.Accumulator import Control.Exception (assert) #if !MIN_VERSION_base(4,8,0) import Data.Foldable import Data.Monoid #endif main = do putStrLn one assert (one == "[3,2,1]") $ return () putStrLn two assert (two == "aaa\"TEST\"bbb123cccTrueddd") $ return () putStrLn three assert (three == "3") $ return () one = show (polyvariadic mempty (id :: [Int] -> [Int]) (1::Int) (2::Int) (3::Int) :: [Int]) two = printf' "aaa%bbb%ccc%ddd" "TEST" 123 True 1.2 three = show (apply ((+) :: Int -> Int -> Int) ([1,2] :: [Int]) :: Int) magicChar = '%' data PrintfAccum = PrintfAccum { done :: String, todo :: String } instance Show x => Accumulator PrintfAccum x where accumulate x (PrintfAccum done (_:todo)) = PrintfAccum (done ++ show x ++ takeWhile (/= magicChar) todo) (dropWhile (/= magicChar) todo) accumulate _ acc = acc printf' str = polyvariadic (PrintfAccum (takeWhile (/= magicChar) str) (dropWhile (/= magicChar) str)) done