module Exon.Class.Newtype where
import Exon.Data.Segment (Segment)
import Exon.Generic (IsNewtype, OverNt)
import Unsafe.Coerce (unsafeCoerce)
class OverNewtype (current :: Type) (wrapped :: Maybe Type) (inner :: Type) | current -> inner where
overNewtype :: (NonEmpty (Segment inner) -> inner) -> NonEmpty (Segment current) -> current
instance (
OverNt current wrapped,
IsNewtype wrapped next,
OverNewtype wrapped next inner
) => OverNewtype current ('Just wrapped) inner where
overNewtype :: (NonEmpty (Segment inner) -> inner)
-> NonEmpty (Segment current) -> current
overNewtype NonEmpty (Segment inner) -> inner
f NonEmpty (Segment current)
segments =
wrapped -> current
forall a b. a -> b
unsafeCoerce (forall current (wrapped :: Maybe (*)) inner.
OverNewtype current wrapped inner =>
(NonEmpty (Segment inner) -> inner)
-> NonEmpty (Segment current) -> current
overNewtype @wrapped @next @inner NonEmpty (Segment inner) -> inner
f ((current -> wrapped) -> Segment current -> Segment wrapped
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap current -> wrapped
forall a b. a -> b
unsafeCoerce (Segment current -> Segment wrapped)
-> NonEmpty (Segment current) -> NonEmpty (Segment wrapped)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NonEmpty (Segment current)
segments))
{-# inline overNewtype #-}
instance OverNewtype current 'Nothing current where
overNewtype :: (NonEmpty (Segment current) -> current)
-> NonEmpty (Segment current) -> current
overNewtype =
(NonEmpty (Segment current) -> current)
-> NonEmpty (Segment current) -> current
forall a. a -> a
id
{-# inline overNewtype #-}
class OverNewtypes (result :: Type) (inner :: Type) | result -> inner where
overNewtypes :: (NonEmpty (Segment inner) -> inner) -> NonEmpty (Segment result) -> result
instance (
IsNewtype result wrapped,
OverNewtype result wrapped inner
) => OverNewtypes result inner where
overNewtypes :: (NonEmpty (Segment inner) -> inner)
-> NonEmpty (Segment result) -> result
overNewtypes =
forall current (wrapped :: Maybe (*)) inner.
OverNewtype current wrapped inner =>
(NonEmpty (Segment inner) -> inner)
-> NonEmpty (Segment current) -> current
overNewtype @result @wrapped
{-# inline overNewtypes #-}