{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# OPTIONS_GHC -Wno-name-shadowing #-}
{-# OPTIONS_GHC -Wno-orphans #-}
module Generics.MRSOP.Base.NS
( SOP.NS , pattern Here , pattern There
, mapNS
, mapNSM
, elimNS
, zipNS
, cataNS
, eqNS
) where
import qualified Data.SOP.NS as SOP
import Data.SOP.NS (NS(..))
import Control.Monad
import Generics.MRSOP.Util
pattern There :: forall k (a :: k -> *) (b :: [k]). ()
=> forall (xs :: [k]) (x :: k). (b ~ (x : xs))
=> NS a xs -> NS a b
pattern There x = SOP.S x
pattern Here :: forall k (a :: k -> *) (b :: [k]). ()
=> forall (x :: k) (xs :: [k]). (b ~ (x : xs))
=> a x -> NS a b
pattern Here x = SOP.Z x
{-# COMPLETE Here, There #-}
instance EqHO f => EqHO (NS f) where
eqHO (Here fx) (Here fy) = eqHO fx fy
eqHO (There x) (There y) = eqHO x y
eqHO _ _ = False
instance ShowHO f => ShowHO (NS f) where
showsPrecHO d (Here fx) = showParen (d > app_prec) $
showString "Here " . showsPrecHO (app_prec+1) fx
where app_prec = 10
showsPrecHO d (There fx) = showParen (d > app_prec) $
showString "There " . showsPrecHO (app_prec+1) fx
where app_prec = 10
mapNS :: f :-> g -> NS f ks -> NS g ks
mapNS f (Here p) = Here (f p)
mapNS f (There p) = There (mapNS f p)
mapNSM :: (Monad m) => (forall x . f x -> m (g x)) -> NS f ks -> m (NS g ks)
mapNSM f (Here p) = Here <$> f p
mapNSM f (There p) = There <$> mapNSM f p
elimNS :: (forall x . f x -> a) -> NS f ks -> a
elimNS f (Here p) = f p
elimNS f (There p) = elimNS f p
zipNS :: (MonadPlus m) => NS ki xs -> NS kj xs -> m (NS (ki :*: kj) xs)
zipNS (Here p) (Here q) = return (Here (p :*: q))
zipNS (There p) (There q) = There <$> zipNS p q
zipNS _ _ = mzero
cataNS :: (forall x xs . f x -> r (x ': xs))
-> (forall x xs . r xs -> r (x ': xs))
-> NS f xs -> r xs
cataNS fHere _fThere (Here x) = fHere x
cataNS fHere fThere (There x) = fThere (cataNS fHere fThere x)
eqNS :: (forall x. p x -> p x -> Bool)
-> NS p xs -> NS p xs -> Bool
eqNS p x = maybe False (elimNS $ uncurry' p) . zipNS x