{-# LANGUAGE TypeFamilies #-} -- | -- The `build` function can be used to construct multi-line string literals in -- a monadic way: -- -- > {-# LANGUAGE OverloadedStrings #-} -- > -- > import Data.String.Builder -- > -- > mystring :: String -- > mystring = build $ do -- > "foo" -- > "bar" -- > "baz" module Data.String.Builder ( -- * Functions build , literal -- * Types , Builder , BuilderM ) where import Data.String -- | A writer monad for string literals. data BuilderM a = BuilderM a ShowS instance Monad BuilderM where return a = BuilderM a id BuilderM a xs >>= f = case f a of BuilderM b ys -> BuilderM b (xs . ys) type Builder = BuilderM () -- | Add a literal string. literal :: String -> Builder literal = BuilderM () . showString instance (a ~ ()) => IsString (BuilderM a) where fromString s = literal s >> literal "\n" -- | Run a builder. build :: Builder -> String build (BuilderM () s) = s ""