Gh c не может сделать вывод об использовании экземпляров mtl, несмотря на записи в контексте функции - PullRequest
1 голос
/ 05 мая 2020

У меня есть 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)

Несмотря на безумное количество аннотаций типов и уверенность в том, что ни одна из них не блокирует gh c от каких-либо выводов, я не могу найти выхода из этой ошибки. Я могу сделать вывод, что я каким-то образом создаю / делаю вывод об отдельном экземпляре m?

Любые советы или помощь были бы очень признательны.

- E

1 Ответ

2 голосов
/ 05 мая 2020

Если вы внимательно посмотрите на сообщение об ошибке:

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

, вы увидите, что GH C решил, что ему нужен экземпляр MonadLogger для приложения частичной функции. В частности, он пытается использовать экземпляр монады неявного чтения для (->) some_type (что нечетно) и ожидает, что этот тип будет поддерживать ведение журнала (что безумие).

Это означает, что в вашей программе есть ошибка типа.

Мне кажется, что вы хотите, по крайней мере, иметь дополнительную скобку в строке после ошибки:

<*> (Model.fromListReqQualities <$> fullSetReqs')
    ^                                           ^
    `---------------- add these ----------------'
...