module ASCII.Isomorphism ( CharIso (..), asChar, StringIso (..) ) where

import ASCII.Char     ( Char )
import ASCII.Superset ( CharSuperset (..), StringSuperset (..) )
import Data.Function  ( id, (.) )
import Data.List      ( map )

class CharSuperset char => CharIso char
  where
    toChar :: char -> Char

asChar :: CharIso char => (Char -> Char) -> char -> char
asChar :: (Char -> Char) -> char -> char
asChar Char -> Char
f = Char -> char
forall char. CharSuperset char => Char -> char
fromChar (Char -> char) -> (char -> Char) -> char -> char
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Char
f (Char -> Char) -> (char -> Char) -> char -> Char
forall b c a. (b -> c) -> (a -> b) -> a -> c
. char -> Char
forall char. CharIso char => char -> Char
toChar

class StringSuperset string => StringIso string
  where
    toCharList :: string -> [Char]
    mapChars :: (Char -> Char) -> string -> string

-- | 'Char' is trivially isomorphic to itself. (This instance is uninteresting.)
instance CharIso Char
  where
    toChar :: Char -> Char
toChar = Char -> Char
forall a. a -> a
id

instance CharIso char => StringIso [char]
  where
    toCharList :: [char] -> [Char]
toCharList = (char -> Char) -> [char] -> [Char]
forall a b. (a -> b) -> [a] -> [b]
map char -> Char
forall char. CharIso char => char -> Char
toChar
    mapChars :: (Char -> Char) -> [char] -> [char]
mapChars Char -> Char
f = (char -> char) -> [char] -> [char]
forall a b. (a -> b) -> [a] -> [b]
map ((Char -> Char) -> char -> char
forall char. CharIso char => (Char -> Char) -> char -> char
asChar Char -> Char
f)