{-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE StarIsType #-} {-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeApplications #-} module Data.Managed.Encoding where import Data.Kind (Type) class Encoding a where type In a :: Type type Out a :: Type class Encode t rep where encode :: t -> Out rep class Decode t rep where decode :: In rep -> Maybe t withEncoding :: forall e i o. (Encode o e, Decode i e) => (i -> o) -> In e -> Maybe (Out e) withEncoding :: (i -> o) -> In e -> Maybe (Out e) withEncoding i -> o f In e i = do i decoded <- In e -> Maybe i forall t rep. Decode t rep => In rep -> Maybe t decode @i @e In e i let applied :: o applied = i -> o f i decoded Out e -> Maybe (Out e) forall (m :: * -> *) a. Monad m => a -> m a return (Out e -> Maybe (Out e)) -> Out e -> Maybe (Out e) forall a b. (a -> b) -> a -> b $ o -> Out e forall t rep. Encode t rep => t -> Out rep encode @o @e o applied