{-# LANGUAGE GeneralizedNewtypeDeriving, GADTs #-} -- | -- `build` 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" -- -- `return` and `>>=` are not useful in this context! module Data.String.Builder (build, Builder, BuilderM) where import Data.String import Control.Monad.Trans.Writer newtype BuilderM a = BuilderM { runBuilderM :: Writer String a } deriving Monad type Builder = BuilderM () literal :: String -> Builder literal = BuilderM . tell instance (a ~ ()) => IsString (BuilderM a) where fromString s = literal s >> literal "\n" >> return () build :: Builder -> String build = snd . runWriter . runBuilderM