hpaste

recent | annotate | new

module Data.StringClass
    ( StringClass(..)
    , convertString )
    where

import qualified Data.ByteString.Char8 as BS (ByteString, pack, unpack, concat)
import qualified Data.ByteString.Lazy.Char8 as BL (ByteString, pack, unpack, toChunks, fromChunks)

class StringClass a where
    toString   :: a -> String
    fromString :: String -> a


instance StringClass String where
    toString   = id
    fromString = id


instance StringClass BS.ByteString where
    toString   = BS.unpack
    fromString = BS.pack


instance StringClass BL.ByteString where
    toString   = BL.unpack
    fromString = BL.pack


convertString :: (StringClass a, StringClass b) => a -> b
convertString = fromString . toString
{- #RULES
"convertString/String->String" convertString = id
"convertString/Strict->Strict" convertString = id
"convertString/Lazy->Lazy"     convertString = id
"convertString/Strict->Lazy"   convertString = BL.fromChunks . (:[])
"convertString/Lazy->Strict"   convertString = BS.concat . BL.toChunks
-}


convertString :: (StringClass a, StringClass b) => a -> b
convertString = fromString . toString
{- #RULES
"convertString/String->String" forall x. toString (fromString x) = id
"convertString/Strict->Strict" forall x. toString (fromString x) = id
"convertString/Lazy->Lazy"     forall x. toString (fromString x) = id
"convertString/Strict->Lazy"   forall x. toString (fromString x) = BL.fromChunks . (:[])
"convertString/Lazy->Strict"   forall x. toString (fromString x) = BS.concat . BL.toChunks
-}


convertString :: (StringClass a, StringClass b) => a -> b
convertString = fromString . toString
{- #RULES
"convertString/id"             forall x. fromString (toString x) = x
"convertString/Strict->Lazy"   forall x. fromString (toString x) = BL.fromChunks [x]
"convertString/Lazy->Strict"   forall x. fromString (toString x) = BS.concat (BL.toChunks x)
-}


{-# OPTIONS_GHC -fglasgow-exts -O #-}

import qualified Data.ByteString.Char8 as BS
import qualified Data.ByteString.Lazy.Char8 as BL

class StringClass a where
    toString   :: a -> String
    fromString :: String -> a


instance StringClass String where
    toString   = id
    fromString = id


instance StringClass BS.ByteString where
    toString   = BS.unpack
    fromString = BS.pack


instance StringClass BL.ByteString where
    toString   = BL.unpack
    fromString = BL.pack


convertString :: (StringClass a, StringClass b) => a -> b
convertString x = fromString (toString x)

{-# RULES
"convertString/Strict->Lazy"   convertString = BL.fromChunks . (:[])
"convertString/Lazy->Strict"   convertString = BS.concat . BL.toChunks
 #-}

-- this one is dangerous, it is probably better to make 'id' rules for types
-- for which this property holds.
{-# RULES "convertString/a->a" convertString = id #-}

-- testing:
main = do
    -- test Strict->Lazy
    print $ BL.null $ convertString $ BS.singleton '0'
    -- test Lazy->Strict
    print $ BS.null $ convertString $ BL.singleton '1'
    -- test a->a
    print $ BS.null $ convertString $ BS.singleton '2'
    -- test a->a
    print $ BL.null $ convertString $ BL.singleton '3'