尽管函数上下文中有条目,但 Ghc 无法推断 mtl 实例的使用
Ghc can't infer the use of mtl instances despite entries in the function context
我有一个 API 可以帮助从大量记录链中提取值。这是函数定义之一。其他示例,使用日志类型类功能。
-- |
-- Unifying filter for FieldValues
-- The "failed" search returns a null set.
--
filterValues, filterQualReqValues
:: (MonadLogger m, MonadThrow m)
=> FieldValues -> FieldValues
-> m FieldValues
filterValues (TxtSet s) (TxtSet vs) = pure . TxtSet $ Set.intersection s vs
filterValues (IntSet s) (IntSet vs) = pure . IntSet $ Set.intersection s vs
filterValues (SpanSet s) (SpanSet vs) = pure . SpanSet $ Set.intersection s vs
filterValues s _ = throw $ TypeException (Just . pack $ show s)
filterQualReqValues = filterValues
我尝试使用 API...
fetchQualities :: (MonadLogger m, MonadThrow m)
=> [GqlInput.QualityReqInput] -> Model.Qualities
-> m (Maybe Model.ReqQualities)
fetchQualities requests etl =
let
-- wrap, process using shared logic, unwrap
(subSetReqs, fullSetReqs) = mapTuple (catMaybes . (fmap unWrapQual))
$ ppSubsetting (Qual <$> requests)
fullSetReqs' :: (MonadLogger m, MonadThrow m)
=> m [(Model.QualName, Maybe Model.QualValues)]
fullSetReqs' = catMaybes <$> traverse (`fetchFullSet` etl) fullSetReqs
subSetReqs' :: (MonadLogger m, MonadThrow m)
=> m [(Model.QualName, Maybe Model.QualValues)]
subSetReqs' = catMaybes <$> traverse (`fetchSubset` etl) subSetReqs
result :: (MonadLogger m, MonadThrow m)
=> m Model.ReqQualities
result = (<>) <$> (Model.fromListReqQualities <$> subSetReqs') -- <<< subSetReqs' error
<*> Model.fromListReqQualities <$> fullSetReqs'
in
do
result' :: Model.ReqQualities <- result
if Model.null result' then pure Nothing
else pure $ Just result'
where
fetchSubset :: (MonadLogger m, MonadThrow m)
=> GqlInput.QualityReqInput
-> Model.Qualities
-> m (Maybe (Model.QualName, Maybe Model.QualValues))
fetchSubset req etl' = do
-- process key
reqWithValues <- getEtlFragment req etl' :: (MonadLogger m, MonadThrow m) => m (Maybe (Model.QualName, Model.QualValues))
case reqWithValues of
Nothing -> pure Nothing
Just (key, etlValues) -> do
-- process values
let valuesReq = GqlInput.qualityValues req -- :: Maybe GqlInput.QualValuesInput
case valuesReq of
Nothing -> pure $ Just (key, Nothing)
Just valuesReq' -> do
let valuesReq'' = fromInputReqQualValues valuesReq'
values <- filterQualReqValues valuesReq'' etlValues
if Model.null values then pure Nothing
else pure $ Just (key, Just values)
fetchFullSet :: (MonadLogger m, MonadThrow m)
=> GqlInput.QualityReqInput
-> Model.Qualities
-> m (Maybe (Model.QualName, Maybe Model.QualValues))
fetchFullSet req etl' = do
let reqName = getQualName req
case reqName of
Nothing -> pure Nothing -- no key in the request
Just name -> do
key <- lookupQualityKey (Model.mkQualKey name) etl'
pure ((,Nothing) <$> key) -- key determines return
我收到一个错误
• Could not deduce (MonadLogger
((->) [(Model.ETL.Key.QualKey, Maybe Model.QualValues)]))
arising from a use of ‘subSetReqs'’
from the context: (MonadLogger m, MonadThrow m)
bound by the type signature for:
fetchQualities :: forall (m :: * -> *).
(MonadLogger m, MonadThrow m) =>
[GqlInput.QualityReqInput]
-> Model.Qualities -> m (Maybe Model.ReqQualities)
at src/Api/GQL/Input/SubRequest.hs:(143,1)-(145,46)
尽管类型注释数量惊人,并确保其中 none 实际上阻止了 ghc 推断某些东西,但我无法找到解决此错误的方法。我可以推断出我是 creating/inferring m
?
的一个单独实例
如有任何建议或帮助,我们将不胜感激。
- E
如果您仔细查看错误消息:
Could not deduce (MonadLogger
((->) [(Model.ETL.Key.QualKey, Maybe Model.QualValues)]))
arising from a use of subSetReqs'
您看到 GHC 已经决定它需要一个 MonadLogger
实例用于部分功能应用程序。具体来说,它试图为 (->) some_type
使用隐式 reader monad 实例(这很奇怪)并期望该类型支持日志记录(这很疯狂)。
这意味着您的程序中存在类型错误。
在我看来,您至少希望在错误 之后的 行中添加一些额外的括号:
<*> (Model.fromListReqQualities <$> fullSetReqs')
^ ^
`---------------- add these ----------------'
我有一个 API 可以帮助从大量记录链中提取值。这是函数定义之一。其他示例,使用日志类型类功能。
-- |
-- Unifying filter for FieldValues
-- The "failed" search returns a null set.
--
filterValues, filterQualReqValues
:: (MonadLogger m, MonadThrow m)
=> FieldValues -> FieldValues
-> m FieldValues
filterValues (TxtSet s) (TxtSet vs) = pure . TxtSet $ Set.intersection s vs
filterValues (IntSet s) (IntSet vs) = pure . IntSet $ Set.intersection s vs
filterValues (SpanSet s) (SpanSet vs) = pure . SpanSet $ Set.intersection s vs
filterValues s _ = throw $ TypeException (Just . pack $ show s)
filterQualReqValues = filterValues
我尝试使用 API...
fetchQualities :: (MonadLogger m, MonadThrow m)
=> [GqlInput.QualityReqInput] -> Model.Qualities
-> m (Maybe Model.ReqQualities)
fetchQualities requests etl =
let
-- wrap, process using shared logic, unwrap
(subSetReqs, fullSetReqs) = mapTuple (catMaybes . (fmap unWrapQual))
$ ppSubsetting (Qual <$> requests)
fullSetReqs' :: (MonadLogger m, MonadThrow m)
=> m [(Model.QualName, Maybe Model.QualValues)]
fullSetReqs' = catMaybes <$> traverse (`fetchFullSet` etl) fullSetReqs
subSetReqs' :: (MonadLogger m, MonadThrow m)
=> m [(Model.QualName, Maybe Model.QualValues)]
subSetReqs' = catMaybes <$> traverse (`fetchSubset` etl) subSetReqs
result :: (MonadLogger m, MonadThrow m)
=> m Model.ReqQualities
result = (<>) <$> (Model.fromListReqQualities <$> subSetReqs') -- <<< subSetReqs' error
<*> Model.fromListReqQualities <$> fullSetReqs'
in
do
result' :: Model.ReqQualities <- result
if Model.null result' then pure Nothing
else pure $ Just result'
where
fetchSubset :: (MonadLogger m, MonadThrow m)
=> GqlInput.QualityReqInput
-> Model.Qualities
-> m (Maybe (Model.QualName, Maybe Model.QualValues))
fetchSubset req etl' = do
-- process key
reqWithValues <- getEtlFragment req etl' :: (MonadLogger m, MonadThrow m) => m (Maybe (Model.QualName, Model.QualValues))
case reqWithValues of
Nothing -> pure Nothing
Just (key, etlValues) -> do
-- process values
let valuesReq = GqlInput.qualityValues req -- :: Maybe GqlInput.QualValuesInput
case valuesReq of
Nothing -> pure $ Just (key, Nothing)
Just valuesReq' -> do
let valuesReq'' = fromInputReqQualValues valuesReq'
values <- filterQualReqValues valuesReq'' etlValues
if Model.null values then pure Nothing
else pure $ Just (key, Just values)
fetchFullSet :: (MonadLogger m, MonadThrow m)
=> GqlInput.QualityReqInput
-> Model.Qualities
-> m (Maybe (Model.QualName, Maybe Model.QualValues))
fetchFullSet req etl' = do
let reqName = getQualName req
case reqName of
Nothing -> pure Nothing -- no key in the request
Just name -> do
key <- lookupQualityKey (Model.mkQualKey name) etl'
pure ((,Nothing) <$> key) -- key determines return
我收到一个错误
• Could not deduce (MonadLogger
((->) [(Model.ETL.Key.QualKey, Maybe Model.QualValues)]))
arising from a use of ‘subSetReqs'’
from the context: (MonadLogger m, MonadThrow m)
bound by the type signature for:
fetchQualities :: forall (m :: * -> *).
(MonadLogger m, MonadThrow m) =>
[GqlInput.QualityReqInput]
-> Model.Qualities -> m (Maybe Model.ReqQualities)
at src/Api/GQL/Input/SubRequest.hs:(143,1)-(145,46)
尽管类型注释数量惊人,并确保其中 none 实际上阻止了 ghc 推断某些东西,但我无法找到解决此错误的方法。我可以推断出我是 creating/inferring m
?
如有任何建议或帮助,我们将不胜感激。
- E
如果您仔细查看错误消息:
Could not deduce (MonadLogger
((->) [(Model.ETL.Key.QualKey, Maybe Model.QualValues)]))
arising from a use of subSetReqs'
您看到 GHC 已经决定它需要一个 MonadLogger
实例用于部分功能应用程序。具体来说,它试图为 (->) some_type
使用隐式 reader monad 实例(这很奇怪)并期望该类型支持日志记录(这很疯狂)。
这意味着您的程序中存在类型错误。
在我看来,您至少希望在错误 之后的 行中添加一些额外的括号:
<*> (Model.fromListReqQualities <$> fullSetReqs')
^ ^
`---------------- add these ----------------'