我有以下模块,基于higgledy README的示例及其源代码。
{-# 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
似乎我已经忠实地再现了他们在getLabel
签名的第一部分的field
价值,但仍然有些不对劲:
• 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
| ^^^^^^^^^^^^
我可以直接在同一个代码库中使用 higgledy 的field
实现,例如:
sxLabels :: Labels SxRecord
sxLabels = textLabel @SxRecord
markKey :: Text
markKey = getConst $ sxLabels ^. field @"mark"
那么为什么这在第一种情况下不起作用呢?有修复吗?
您的签名要求HKD structure f
HasField'
(对于某些未知f
(,但您实际上是在尝试在HKD structure (Const Text)
上使用field'
。因此,"缺少实例"错误。
您需要将约束中的f
替换为Const Text
并摆脱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