hypertypes-0.1.0.1: src/Hyper/Type/AST/Map.hs
{-# LANGUAGE TemplateHaskell, FlexibleInstances, UndecidableInstances #-}
module Hyper.Type.AST.Map
( TermMap(..), _TermMap, W_TermMap(..), MorphWitness(..)
) where
import qualified Control.Lens as Lens
import qualified Data.Map as Map
import Hyper
import Hyper.Class.ZipMatch (ZipMatch(..))
import Hyper.Internal.Prelude
-- | A mapping of keys to terms.
--
-- Apart from the data type, a 'ZipMatch' instance is also provided.
newtype TermMap h expr f = TermMap (Map h (f :# expr))
deriving stock Generic
makePrisms ''TermMap
makeCommonInstances [''TermMap]
makeHTraversableApplyAndBases ''TermMap
makeHMorph ''TermMap
instance Eq h => ZipMatch (TermMap h expr) where
{-# INLINE zipMatch #-}
zipMatch (TermMap x) (TermMap y)
| Map.size x /= Map.size y = Nothing
| otherwise =
zipMatchList (x ^@.. Lens.itraversed) (y ^@.. Lens.itraversed)
<&> traverse . Lens._2 %~ uncurry (:*:)
<&> TermMap . Map.fromAscList
{-# INLINE zipMatchList #-}
zipMatchList :: Eq k => [(k, a)] -> [(k, b)] -> Maybe [(k, (a, b))]
zipMatchList [] [] = Just []
zipMatchList ((k0, v0) : xs) ((k1, v1) : ys)
| k0 == k1 =
zipMatchList xs ys <&> ((k0, (v0, v1)) :)
zipMatchList _ _ = Nothing