{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
module Versioning.Upgrade
( Adapt(..)
, Upgrade(..)
, upgrade
)
where
import Data.Kind (Type)
import Versioning.Base
import Versioning.Internal.Folding (Incr)
class Adapt (v :: V) (w :: V) (a :: V -> Type) where
adapt :: a v -> a w
upgrade :: Upgrade v w a => a v -> a w
upgrade = upgrade'
class Upgrade (v :: V) (w :: V) (a :: V -> Type) where
upgrade' :: a v -> a w
instance {-# OVERLAPS #-} Upgrade v v a where
upgrade' x = x
instance {-# OVERLAPPABLE #-} (Adapt v (Incr v w) a, Upgrade (Incr v w) w a)
=> Upgrade v w a where
upgrade' x = upgrade' @(Incr v w) @w (adapt @v @(Incr v w) x)