{-# LANGUAGE GADTs #-}
module Data.HashMap.InsOrd.Internal where
import Prelude ()
import Prelude.Compat hiding (filter, foldr, lookup, map, null)
import Control.Applicative ((<**>))
data SortedAp f a where
Pure :: a -> SortedAp f a
SortedAp :: !Int -> f a -> SortedAp f (a -> b) -> SortedAp f b
instance Functor (SortedAp f) where
fmap f (Pure a) = Pure (f a)
fmap f (SortedAp i x y) = SortedAp i x ((f .) <$> y)
instance Applicative (SortedAp f) where
pure = Pure
Pure f <*> y = fmap f y
f <*> Pure y = fmap ($ y) f
f@(SortedAp i x y) <*> z@(SortedAp j u v)
| i < j = SortedAp i x (flip <$> y <*> z)
| otherwise = SortedAp j u ((.) <$> f <*> v)
liftSortedAp :: Int -> f a -> SortedAp f a
liftSortedAp i x = SortedAp i x (Pure id)
retractSortedAp :: Applicative f => SortedAp f a -> f a
retractSortedAp (Pure x) = pure x
retractSortedAp (SortedAp _ f x) = f <**> retractSortedAp x