Skip to content

Instantly share code, notes, and snippets.

@phadej
Last active December 28, 2021 16:04
Show Gist options
  • Save phadej/75b826c6f8dec5b41955edfb5041e6d7 to your computer and use it in GitHub Desktop.
Save phadej/75b826c6f8dec5b41955edfb5041e6d7 to your computer and use it in GitHub Desktop.
import Debug.Trace (traceM)
import Data.String (IsString (..))
-- $setup
-- >>> :set -XOverloadedStrings
-- | A formatter.
--
-- The power of simple Haskell.
--
-- >>> printIO "hello world"
-- hello world
--
-- >>> printIO str "foo"
-- foo
--
-- >>> printIO ("TODO" # str # "or" # str) "foo" "bar"
-- TODO foo or bar
--
newtype Formatter r a b = Formatter ((r -> b) -> a)
instance (IsString r, a ~ b) => IsString (Format r a b) where
fromString s = Format $ \kont -> kont (fromString s)
-- | Format and print to stdout'
printIO :: Formatter Words ys (IO ()) -> ys
printIO (Formatter k) = k $ putStrLn . runWords
-- | String argument.
str :: IsString r => Formatter r (String -> a) a
str = Format $ \kont s -> kont (fromString s)
-- | Concatenate 'Formatter's.
--
-- Semantics depend on 'Semigroup' instance of @r@ argument.
-- @Words@ intersperses spaces.
--
(#) :: Semigroup r => Formatter r a b -> Formatter r b c -> Formatter r a c
Formatter f # Formatter g = Formatter $ \kont -> f $ \xs -> g $ \ys -> kont (xs <> ys)
-- | Words builder.
newtype Words = Words ShowS
runWords :: Words -> String
runWords (Words w) = w ""
instance IsString Words where
fromString = Words . showString
instance Semigroup Words where
Words x <> Words y = Words (x . showChar ' ' . y)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment