Невозможно вывести (показать a10), возникающее в результате использования «def» - PullRequest
0 голосов
/ 07 ноября 2018

Я застрял на этой ошибке довольно долгое время. Я не уверен, что я глуп, но не вижу, откуда это идет ...

Тип данных Settings определяется следующим образом:

data Settings a = Settings { 
         _nodeDrawFunction :: a -> Diagram B
       , _dynamicHead :: Measure Double
       , _dynamicThick :: Measure Double
       , _directed :: Directed
       , _horizontalOrientation :: Maybe Bool
       , _layerSpacing :: Maybe Double
       , _nodeSpacing :: Maybe Double
       , _graphPadding :: Maybe Double
       , _colF :: Maybe (Int -> Colour Double)
       , _bgOp :: Maybe Double
       , _initPos :: Maybe Int
      }

И makeLenses ''Settings используется для создания линз для каждой записи. По умолчанию для _drawNodeFunction установлено drawDefaultNode.

Когда я создаю функцию, перезаписывающую некоторые из этих значений с помощью сеттеров линз, она работает нормально, например:

test1 :: (Show a) => Graph a -> Settings a
test1 g = def & bgOp .~ Just 1

Который работает как положено. Тип Graph взят из библиотеки алгебраических графов.

Если я попытаюсь установить nodeDrawFunction, например, с помощью:

test2 :: (Show a) => Graph a -> Settings a
test2 g = def & nodeDrawFunction .~ drawDefaultNode
              & bgOp .~ Just 1

Произошла следующая ошибка:

Could not deduce (Show a10) arising from a use of ‘def’
  from the context: Show a
    bound by the type signature for:
               test2 :: forall a. Show a => Graph a -> Settings a
    at Visualise/Hierarchical.hs:78:1-42
  The type variable ‘a10’ is ambiguous
  These potential instances exist:
    instance Show n => Show (Duration n) -- Defined in ‘Data.Active’
    instance Show n => Show (Era n) -- Defined in ‘Data.Active’
    instance Show n => Show (Time n) -- Defined in ‘Data.Active’
    ...plus 74 others
    ...plus 264 instances involving out-of-scope types
    (use -fprint-potential-instances to see them all)
• In the first argument of ‘(&)’, namely ‘def’
  In the first argument of ‘(&)’, namely
    ‘def & nodeDrawFunction .~ drawDefaultNode’
  In the expression:
    def & nodeDrawFunction .~ drawDefaultNode & bgOp .~ Just 1

Даже если я попытаюсь установить для nodeDrawFunction значение по умолчанию (как и для любой другой допустимой функции).

Любая помощь будет высоко ценится, спасибо!

1 Ответ

0 голосов
/ 07 ноября 2018

Возможно, вы предполагаете, что def и def & nodeDrawFunction .~ drawDefaultNode имеют одинаковый тип. nodeDrawFunction достаточно гибок, чтобы позволить им иметь различные типы, Settings a и Settings a10. GHC начинает с этого более общего предположения, а затем не может выбрать конкретный тип для a10, поскольку он не ограничен ничем в функции.

Один из вариантов - определить nodeDrawFunction с менее общим типом.

Другой вариант - добавить сигнатуру типа на def для руководства GHC. Я думаю, что это будет работать, если вы добавите -XScopedTypeVariables:

(def :: Settings a) & nodeDrawFunction .~ drawDefaultNode

Без ScopedTypeVariables две переменные типа a интерпретируются как разные, и перед проверкой типа им присваиваются разные уникальные имена. Если бы у вас было несколько полей в Settings, которые включают a, makeLenses вывели бы линзы, которые не могут изменить a, поскольку ни одна линза с одним полем не смогла бы это сделать.

...