{-# LANGUAGE FlexibleContexts, FlexibleInstances, MultiParamTypeClasses, UndecidableInstances #-}
module Data.Monoid.FromString 
    ( FromString(FromString,getFromString)
    ) where

import Control.Functor.Pointed
import Data.Monoid.Generator
import Data.Monoid.Reducer
import GHC.Exts

data FromString m = FromString { getFromString :: m } 

instance Monoid m => Monoid (FromString m) where
    mempty = FromString mempty
    FromString a `mappend` FromString b = FromString (a `mappend` b)

instance Reducer Char m => Reducer Char (FromString m) where
    unit = FromString . unit

instance Reducer Char m => IsString (FromString m) where
    fromString = FromString . reduce

instance Pointed FromString where
    point = FromString

instance Copointed FromString where
    extract = getFromString

instance Functor FromString where
    fmap f (FromString x) = FromString (f x)