Я получаю следующую ошибку при попытке использовать 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, это также полезно знать для справок в будущем.