Как наследовать экземпляры параметри c от общего класса к более специализированному (или просто немного другому) классу? - PullRequest
1 голос
/ 18 июня 2020

Я получаю следующую ошибку при попытке использовать API, над которым я работал:

/home/bebarker/workspace/DouglasMetabolicModels/src/COBRA/MATLAB/Engine/Util.hs:14:9: warning: [-Wsimplifiable-class-constraints]
    • The constraint ‘MXArrayComponent a’
        matches an instance declaration
      instance Foreign.Matlab.Array.MXArrayComponent a =>
               MXArrayComponent a
        -- Defined in ‘Foreign.Matlab.ZIOArray’
      This makes type inference for inner bindings fragile;
        either use MonoLocalBinds, or simplify it using the instance
    • In the type signature:
        disp :: (HasEngine r, MXArrayComponent a) =>
                MXArray a -> ZIO r MatlabException ()

Это происходит в определении функции:

disp :: (HasEngine r, MXArrayComponent a) => MXArray a -> ZIO r MatlabException ()
disp arr = engineEvalFun "disp" [EvalArray arr] 0 <&> discard

Базовый класс выглядит так в Array.hs:

-- |The class of standardly typeable array elements
class MXArrayComponent a where
  -- |Determine whether the given array is of the correct type
  isMXArray :: MXArray a -> MIO Bool
  ... more stuff

И экземпляр в том же модуле выглядит так:

-- |Complex array access.
instance (RealFloat a, MNumeric a, MXArrayData mx a) => MXArrayComponent (MComplex a) where
  isMXArray = isMXArrayMComplex
  createMXArray = createMXArrayMComplex
  mxArrayGetOffset = mxArrayGetOffsetMComplex
  mxArraySetOffset = mxArraySetOffsetMComplex
  mxArrayGetOffsetList = mxArrayGetOffsetListMComplex
  mxArraySetOffsetList = mxArraySetOffsetListMComplex

Затем в другом модуле (ZIOArray.hs) я получил аналогичный класс, который в некоторых случаях использует ZIO вместо IO:

-- |The class of standardly typeable array elements
class MXArrayComponent a where
  -- |Determine whether the given array is of the correct type
  isMXArray :: MXArray a -> ZIO r MatlabException Bool
  ... more stuff

В этом случае я автоматически получаю все экземпляры параметрически:

instance A.MXArrayComponent a => MXArrayComponent a where
  isMXArray = ezlift . EA.isMXArray
  createMXArray = ezlift . EA.createMXArray
  createMXScalar = ezlift . EA.createMXScalar
  isMXScalar = ezlift . EA.isMXScalar
  mxScalarGet = ezlift . EA.mxScalarGet
  createRowVector = ezlift . EA.createRowVector
  mxArrayGetOffset a o = ezlift $ EA.mxArrayGetOffset a o
  mxArraySetOffset a o mcv = ezlift $ EA.mxArraySetOffset a o mcv
  mxArrayGetOffsetList a o n = ezlift $ EA.mxArrayGetOffsetList a o n
  mxArraySetOffsetList a o v = ezlift $ EA.mxArraySetOffsetList a o v

Что такое лучший способ справиться с этой ситуацией? Похоже, что требование, чтобы пользователи использовали MonoLocalBinds только для этого, было бы не идеально.

Мне повезло, что я пишу библиотеку, так что это дает мне некоторую гибкость в определении того, как двигаться дальше, хотя, если есть также ненавязчивый способ справиться с этим на стороне пользователя API, это также полезно знать для справок в будущем.

1 Ответ

1 голос
/ 19 июня 2020

Для экземпляра:

import qualified Foreign.Matlab.Array as A
instance A.MXArrayComponent a => MXArrayComponent a

похоже, что ваш локальный класс MXArrayComponent избыточен. Класс типов, которые он описывает, в точности описывается существующим классом A.MXArrayComponent. Его единственная цель - служить контейнером для сигнатур типов (class) и реализаций (единственного instance), но вам не нужен или не нужен класс для этого.

Итак, удалите ваш class MXArrayComponent, вместо этого повторно экспортируйте базовый класс A.MXArrayComponent и напишите «методы» на верхнем уровне с ограничением, используя реэкспортированный базовый класс:

module ZIOArray 
  (..., A.MXArrayComponent, ...)
  where

import qualified Foreign.Matlab.Array as A

isMXArray :: A.MXArrayComponent a => MXArray a -> ZIO r MatlabException Bool
isMXArray = ezlift . A.isMXArray

-- etc.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...