Sam Prescott
Sam Prescott

Reputation: 55

Could not deduce (Show a10) arising from a use of ‘def’

I have been stuck on this error for quite a while. I'm not sure if I am being stupid but I cannot see where it is coming from...

The data type Settings is defined as so:

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
      }

And makeLenses ''Settings is used to create lenses for each record. The default for _drawNodeFunction is drawDefaultNode.

When I create a function overwriting some of these values using Lens setters it works fine, for example:

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

Which works as expected. The type of Graph is from the library algebraic-graphs.

If I try to set nodeDrawFunction, for example with:

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

The following error is produced:

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

Even if I try to set nodeDrawFunction to the default value (as well as any other valid function).

Any help would be much appreciated, thanks!

Upvotes: 0

Views: 169

Answers (1)

bergey
bergey

Reputation: 3081

You probably intend that def and def & nodeDrawFunction .~ drawDefaultNode have the same type. nodeDrawFunction is flexible enough to allow them to have different types, Settings a and Settings a10. GHC is starting with this more general assumption, and then can't pick a specific type for a10, since it's not constrained by anything in the function.

One option is to define nodeDrawFunction with a less general type.

Another option is to add a type signature on def to guide GHC. I think this will work if you add -XScopedTypeVariables:

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

Without ScopedTypeVariables the two type variables a are interpreted as different, and given different unique names before type checking. If you had multiple fields in Settings that involve a, makeLenses would derive lenses that cannot change a, since no single-field lens could do so.

Upvotes: 2

Related Questions