Skip to content

Instantly share code, notes, and snippets.

@OlaoluwaM
Last active May 5, 2025 21:39
Show Gist options
  • Save OlaoluwaM/2cdc93cfeab5f0beb357e7a2dba5708d to your computer and use it in GitHub Desktop.
Save OlaoluwaM/2cdc93cfeab5f0beb357e7a2dba5708d to your computer and use it in GitHub Desktop.
row type HasCodec instance attempt
-- Necessary Language extensions
import Autodocodec (HasCodec (codec), bimapCodec, (.=))
import Autodocodec qualified as Auto
import Control.Lens
import Data.Row
import Data.Row.Records ()
import Data.Row.Records qualified as Rec
import Data.Text qualified as T
import GHC.OverloadedLabels (IsLabel (fromLabel))
import Data.Generics.Labels
instance forall r. (AllUniqueLabels r, Forall r HasCodec, Rec.Modify "l" (r .! "l") r ~ r) => HasCodec (Rec r) where
codec =
Auto.object "" $ Rec.fromLabelsA @HasCodec @(Auto.Codec Object (Rec r)) @r bor
where
bor :: (KnownSymbol l, HasCodec a, v ~ a) => Label l -> Auto.Codec Object (Rec r) a
bor l = Auto.requiredFieldWith' (T.pack $ show l) codec Auto..= (\v -> (v ^. #l) :: a)
@OlaoluwaM
Copy link
Author

instance forall r. (AllUniqueLabels r, Forall r HasCodec) => HasCodec (Rec r) where
    codec =
        Auto.object "" $
            getCompose $
                metamorph @_ @r @HasCodec @Const @(Const ()) @_ @Proxy
                    Proxy
                    (\_ -> Compose (pure Rec.empty))
                    (\_ _ -> Const $ Const ())
                    -- (\l (Const (Compose r)) -> Compose $ Rec.extend l <$> Auto.requiredField' (T.pack $ symbolVal l) Auto..= (Rec..! fromLabel l) <*> r)
                    (doCons (\l -> Auto.requiredField' (T.pack $ symbolVal l) Auto..= (^. #l)))
                    (Const ())

doCons :: forall c f  τ ρ. (KnownSymbol , c τ, Rec.HasType  τ ρ) => (Label  -> f τ) -> Label  -> Const (Compose f Rec ρ) (Proxy τ) -> Compose f Rec (Rec.Extend  τ ρ)
doCons mk l (Const (Compose r)) = Compose $ Rec.extend l <$> mk l <*> r

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment