module System.IO.StringLike.Impl (
CanGetContents, CanGetContentsClass (hGetContents), getContents, readFile,
CanGetLine, CanGetLineClass (hGetLine), getLine,
CanPutStr, CanPutStrClass (hPutStr), putStr, writeFile, appendFile,
interact,
CanPutStrLn, CanPutStrLnClass (hPutStrLn), putStrLn,
CanProxyT, CanProxyTo (canProxyTo), CanProxyFrom (canProxyFrom)
) where
import Prelude hiding (
readFile,
writeFile,
appendFile,
getContents,
putStr,
interact,
getLine,
putStrLn
)
import qualified System.IO as IO
import System.IO (Handle, IOMode(ReadMode))
import Data.Semigroup ((<>))
import qualified Data.ByteString.Char8 as BSS
import qualified Data.ByteString.Lazy.Char8 as BSL
import qualified Data.ByteString.Builder as BSB
import qualified Data.Text as TS
import qualified Data.Text.IO as TS
import qualified Data.Text.Lazy as TL
import qualified Data.Text.Lazy.IO as TL
import qualified Data.Text.Lazy.Builder as TB
type CanGetContents t = CanGetContentsClass IO Handle t
class Monad m => CanGetContentsClass m handleT t where
hGetContents :: handleT -> m t
default hGetContents :: (CanProxyFrom t, CanGetContentsClass m handleT (CanProxyT t)) => handleT -> m t
hGetContents = (canProxyFrom <$>) . hGetContents
getContents :: CanGetContents t => IO t
getContents = hGetContents IO.stdin
readFile :: CanGetContents t => FilePath -> IO t
readFile filePath = IO.withFile filePath ReadMode hGetContents
instance (m ~ IO, CanGetContentsClass m Handle t) => CanGetContentsClass m FilePath t where
hGetContents = readFile
type CanGetLine t = CanGetLineClass IO Handle t
class CanGetContentsClass m handleT t => CanGetLineClass m handleT t where
hGetLine :: handleT -> m t
default hGetLine :: (CanProxyFrom t, CanGetLineClass m handleT (CanProxyT t)) => handleT -> m t
hGetLine = (canProxyFrom <$>) . hGetLine
getLine :: CanGetLine t => IO t
getLine = hGetLine IO.stdin
type CanPutStr t = CanPutStrClass IO Handle t
class Monad m => CanPutStrClass m handleT t where
hPutStr :: handleT -> t -> m ()
default hPutStr :: (CanProxyTo t, CanPutStrClass m handleT (CanProxyT t)) => handleT -> t -> m ()
hPutStr handle str = hPutStr handle (canProxyTo str)
putStr :: CanPutStr t => t -> IO ()
putStr = hPutStr IO.stdout
writeFile :: CanPutStr t => FilePath -> t -> IO ()
writeFile f txt = IO.withFile f IO.WriteMode (\hdl -> hPutStr hdl txt)
appendFile :: CanPutStr t => FilePath -> t -> IO ()
appendFile f txt = IO.withFile f IO.AppendMode (\hdl -> hPutStr hdl txt)
interact :: (CanGetContents t, CanPutStr t) => (t -> t) -> IO ()
interact f = getContents >>= (putStr . f)
instance (m ~ IO, CanPutStrClass m Handle t) => CanPutStrClass m FilePath t where
hPutStr = appendFile
type CanPutStrLn t = CanPutStrLnClass IO Handle t
class CanPutStrClass m handleT t => CanPutStrLnClass m handleT t where
hPutStrLn :: handleT -> t -> m ()
default hPutStrLn :: (CanProxyTo t, CanPutStrLnClass m handleT (CanProxyT t)) => handleT -> t -> m ()
hPutStrLn handle str = hPutStrLn handle (canProxyTo str)
putStrLn :: CanPutStrLn t => t -> IO ()
putStrLn s = hPutStrLn IO.stdout s
type family CanProxyT t
class CanProxyTo t where
canProxyTo :: t -> CanProxyT t
class CanProxyFrom t where
canProxyFrom :: CanProxyT t -> t
instance (m ~ IO) => CanGetContentsClass m Handle String where
hGetContents = IO.hGetContents
instance (m ~ IO) => CanGetLineClass m Handle String where
hGetLine = IO.hGetLine
instance (m ~ IO) => CanPutStrLnClass m Handle String where
hPutStrLn = IO.hPutStrLn
instance (m ~ IO) => CanPutStrClass m Handle String where
hPutStr = IO.hPutStr
instance (m ~ IO) => CanGetContentsClass m Handle BSS.ByteString where
hGetContents = BSS.hGetContents
instance (m ~ IO) => CanGetLineClass m Handle BSS.ByteString where
hGetLine = BSS.hGetLine
instance (m ~ IO) => CanPutStrClass m Handle BSS.ByteString where
hPutStr = BSS.hPutStr
instance (m ~ IO) => CanPutStrLnClass m Handle BSS.ByteString where
hPutStrLn = BSS.hPutStrLn
instance (m ~ IO) => CanGetContentsClass m Handle BSL.ByteString where
hGetContents = BSL.hGetContents
instance (m ~ IO) => CanGetLineClass m Handle BSL.ByteString where
hGetLine = (BSL.fromStrict <$>) . BSS.hGetLine
instance (m ~ IO) => CanPutStrClass m Handle BSL.ByteString where
hPutStr = BSL.hPutStr
instance (m ~ IO) => CanPutStrLnClass m Handle BSL.ByteString where
hPutStrLn = BSL.hPutStrLn
instance (Monad m, CanGetContentsClass m Handle BSL.ByteString) => CanGetContentsClass m Handle BSB.Builder where
instance CanGetLineClass m Handle BSL.ByteString => CanGetLineClass m Handle BSB.Builder
instance (m ~ IO) => CanPutStrClass m Handle BSB.Builder where
hPutStr = BSB.hPutBuilder
instance CanPutStrClass m Handle BSB.Builder => CanPutStrLnClass m Handle BSB.Builder where
hPutStrLn handle builder = hPutStr handle (builder <> BSB.char8 '\n')
type instance CanProxyT BSB.Builder = BSL.ByteString
instance CanProxyTo BSB.Builder where
canProxyTo = BSB.toLazyByteString
instance CanProxyFrom BSB.Builder where
canProxyFrom = BSB.lazyByteString
instance (m ~ IO) => CanGetContentsClass m Handle TS.Text where
hGetContents = TS.hGetContents
instance (m ~ IO) => CanGetLineClass m Handle TS.Text where
hGetLine = TS.hGetLine
instance (m ~ IO) => CanPutStrClass m Handle TS.Text where
hPutStr = TS.hPutStr
instance (m ~ IO) => CanPutStrLnClass m Handle TS.Text where
hPutStrLn = TS.hPutStrLn
instance (m ~ IO) => CanGetContentsClass m Handle TL.Text where
hGetContents = TL.hGetContents
instance (m ~ IO) => CanGetLineClass m Handle TL.Text where
hGetLine = TL.hGetLine
instance (m ~ IO) => CanPutStrClass m Handle TL.Text where
hPutStr = TL.hPutStr
instance (m ~ IO) => CanPutStrLnClass m Handle TL.Text where
hPutStrLn = TL.hPutStrLn
instance (Monad m, CanGetContentsClass m Handle TL.Text) => CanGetContentsClass m Handle TB.Builder
instance CanGetLineClass m Handle TL.Text => CanGetLineClass m Handle TB.Builder
instance (Monad m, CanPutStrClass m Handle TL.Text) => CanPutStrClass m Handle TB.Builder
instance CanPutStrLnClass m Handle TL.Text => CanPutStrLnClass m Handle TB.Builder
type instance CanProxyT TB.Builder = TL.Text
instance CanProxyTo TB.Builder where
canProxyTo = TB.toLazyText
instance CanProxyFrom TB.Builder where
canProxyFrom = TB.fromLazyText