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

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

class CharSuperset (char :: Type) => CharIso char where
  toChar :: char -> Char

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

class StringSuperset string => StringIso (string :: Type) 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 = forall a. a -> a
id

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