Could not deduce (TypeClass a0) arising from a use of ‘variable’

400 views Asked by At

I have a type:

type DifferentiableFunction n a = (Function n a, List n (Function n a), String)

Elsewhere I define:

data Something where
  Operator :: Something -> (forall a . Floating a => DifferentiableFunction n a) -> Something

Now I try to pattern match:

case something of
  (Operator s f) -> let (_, _, l) = f in l

I get Could not deduce (Floating a0) arising from a use of ‘f’. I don't understand why this is happening.

1

There are 1 answers

2
bennofs On BEST ANSWER

The problem is that let (_, _. l) = f in l does not specify what type to use for f: it could be DifferentiableFunction n Double or DifferentiableFunction n Float or something else altogether. Because you only use a part which does not depend on a (l is just a String, no matter what a is), the compiler is unable to decide what type f should have (a is ambigious, i.e. the compile does not know what to pick for a).

The solution therefore is to give an explicit type signature for f:

case something of
  (Operator s f) -> let (_, _, l) = (f :: DifferentiableFunction n Double) in l

Or alternatively, lift the String out of the forall:

type DifferentiableFunction n a = (Function n a, List n (Function n a))
data Something where
  Operator :: Something -> (forall a . Floating a => DifferentiableFunction n a) -> String -> Something -- String is not inside the `forall a.`

Now you can get the String without needing to pick a specific a, because it really is independent of a.