I have the following module based on examples from higgledy README as well as the source code thereof.
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
module FDS.UtilTypes where
import Control.Lens ((^.), Const (..))
import qualified Data.Generics.Internal.VL.Lens as G
import qualified Data.Generics.Product as G
import Data.Functor.Const (Const (..))
import Data.Generic.HKD
import Data.Kind (Type)
type Labels a = HKD a (Const Text) -- Every field holds a string.
class TextLabel (structure :: Type) where
textLabel :: HKD structure (Const Text)
getLabel :: forall ft f structure inner.
G.HasField' ft (HKD structure f) (f inner) =>
Labels structure -> Text
getLabel labels = getConst $ labels ^. G.field' @ft
It seems like I've faithfully reproduced their higgledy's field
value in the first part of the signature of getLabel
, but something is still amiss:
• Could not deduce: Data.Generics.Product.Fields.ErrorUnless
ft
(HKD structure (Const Text))
(generic-lens-1.1.0.0:Data.Generics.Internal.Families.Collect.CollectField
ft (GHKD_ (Const Text) (GHC.Generics.Rep structure)))
arising from a use of ‘G.field'’
from the context: G.HasField' ft (HKD structure f) (f inner)
bound by the type signature for:
getLabel :: forall (ft :: ghc-prim-0.5.3:GHC.Types.Symbol) (f :: *
-> *) structure inner.
G.HasField' ft (HKD structure f) (f inner) =>
Labels structure -> Text
at src/FDS/UtilTypes.hs:(45,1)-(47,26)
• In the second argument of ‘(^.)’, namely ‘G.field' @ft’
In the second argument of ‘($)’, namely ‘labels ^. G.field' @ft’
In the expression: getConst $ labels ^. G.field' @ft
• Relevant bindings include
labels :: Labels structure (bound at src/FDS/UtilTypes.hs:48:9)
getLabel :: Labels structure -> Text
(bound at src/FDS/UtilTypes.hs:48:1)
|
48 | getLabel labels = getConst $ labels ^. G.field' @ft
| ^^^^^^^^^^^^
• Could not deduce (Data.Functor.Contravariant.Contravariant
(GHKD_ (Const Text) (GHC.Generics.Rep structure)))
arising from a use of ‘G.field'’
from the context: G.HasField' ft (HKD structure f) (f inner)
bound by the type signature for:
getLabel :: forall (ft :: ghc-prim-0.5.3:GHC.Types.Symbol) (f :: *
-> *) structure inner.
G.HasField' ft (HKD structure f) (f inner) =>
Labels structure -> Text
at src/FDS/UtilTypes.hs:(45,1)-(47,26)
• In the second argument of ‘(^.)’, namely ‘G.field' @ft’
In the second argument of ‘($)’, namely ‘labels ^. G.field' @ft’
In the expression: getConst $ labels ^. G.field' @ft
|
48 | getLabel labels = getConst $ labels ^. G.field' @ft
| ^^^^^^^^^^^^
I can directly use higgledy's field
implementation in the same code base like:
sxLabels :: Labels SxRecord
sxLabels = textLabel @SxRecord
markKey :: Text
markKey = getConst $ sxLabels ^. field @"mark"
So why does this not work in the first case? Is there a fix?
Your signature asks for HasField'
on HKD structure f
(for some unknown f
), but you're actually trying to use field'
on an HKD structure (Const Text)
. Hence the "missing instance" error.
You need to replace f
with Const Text
in the constraint and get rid of f
:
getLabel :: forall ft structure inner.
G.HasField' ft (HKD structure (Const Text)) (Const Text inner) =>
Labels structure -> Text
getLabel labels = getConst $ labels ^. G.field' @ft