尽管函数上下文中有条目,Ghc也无法推断出使用mtl实例

问题描述 投票:1回答:1

我有一个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)

尽管有大量的类型注释,并确保它们中没有一个实际上阻止ghc推断出某些内容,但我找不到解决该错误的方法。我可以推断的是,我以某种方式创建/推断了m的单独实例?

任何建议或帮助将不胜感激。

-E

haskell typeclass monad-transformers
1个回答
0
投票

如果您更接近错误消息:

Could not deduce (MonadLogger
                  ((->) [(Model.ETL.Key.QualKey, Maybe Model.QualValues)]))
arising from a use of subSetReqs'

您会看到,GHC决定部分功能应用程序需要一个MonadLogger实例。具体来说,它正在尝试将隐式阅读器monad实例用于(->) some_type(这很奇怪),并希望该类型支持日志记录(这很疯狂)。

这意味着您的程序中存在类型错误。

在我看来,您至少要在行[[以下错误中附加括号]:

<*> (Model.fromListReqQualities <$> fullSetReqs') ^ ^ `---------------- add these ----------------'
© www.soinside.com 2019 - 2024. All rights reserved.