{-# LANGUAGE Safe #-}
-- | A 'Read' instance for functions, given the input is 'Finite' and
-- 'Ord' and both the input and output are 'Read'.
module Data.Universe.Instances.Read () where

import Data.Universe.Class (Finite (..))

import qualified Data.Map as Map
import qualified Data.Set as Set
import qualified Data.Monoid as Mon

instance (Finite a, Ord a, Read a, Read b) => Read (a -> b) where
  readsPrec :: Int -> ReadS (a -> b)
readsPrec Int
n String
s =
    [ ((Map a b
m Map a b -> a -> b
forall k a. Ord k => Map k a -> k -> a
Map.!), String
s')
    | ([(a, b)]
v, String
s') <- Int -> ReadS [(a, b)]
forall a. Read a => Int -> ReadS a
readsPrec Int
n String
s
    , let m :: Map a b
m = [(a, b)] -> Map a b
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [(a, b)]
v
    , Map a b -> Set a
forall k a. Map k a -> Set k
Map.keysSet Map a b
m Set a -> Set a -> Bool
forall a. Eq a => a -> a -> Bool
== [a] -> Set a
forall a. Ord a => [a] -> Set a
Set.fromList [a]
forall a. Finite a => [a]
universeF
    ]

instance (Finite a, Ord a, Read a) => Read (Mon.Endo a) where
  readsPrec :: Int -> ReadS (Endo a)
readsPrec Int
d = Bool -> ReadS (Endo a) -> ReadS (Endo a)
forall a. Bool -> ReadS a -> ReadS a
readParen (Int
d Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
10) (ReadS (Endo a) -> ReadS (Endo a))
-> ReadS (Endo a) -> ReadS (Endo a)
forall a b. (a -> b) -> a -> b
$ \String
s0 ->
    [ ((a -> a) -> Endo a
forall a. (a -> a) -> Endo a
Mon.Endo a -> a
f, String
s2)
    | (String
"Endo", String
s1) <- ReadS String
lex String
s0
    , (a -> a
f, String
s2) <- Int -> ReadS (a -> a)
forall a. Read a => Int -> ReadS a
readsPrec Int
11 String
s1
    ]