How can I find out what p0 is?

I am trying to understand a compiler error message that refers to a variable of type p0 . In most cases, an error message will tell me that the compiler calls p0 , and something along the lines of β€œp0 is a variable of hard type, connected ...”, but not in this case.

In general, if a compiler error message refers to a variable of the type that it assigned (and not to a variable of type I that refers to the type signature), and it does not tell me where the type variable is bound, how can I understand this?

 {-# LANGUAGE TypeFamilies, FlexibleContexts, MultiParamTypeClasses #-} import Data.List (minimumBy) import Data.Ord (comparing) import qualified Math.Geometry.Grid as G (Grid(..)) import qualified Math.Geometry.GridMap as GM (GridMap(..)) import Prelude hiding (lookup) class Pattern p where type Metric p difference ∷ p β†’ p β†’ Metric p makeSimilar ∷ p β†’ Metric p β†’ p β†’ p data SOM gm kp = SOM { sGridMap :: gm p, sLearningFunction :: Int -> Int -> Metric p, sCounter :: Int } foo :: (Pattern p, Ord v, v ~ Metric p, GM.GridMap gm p, GM.GridMap gm v, k ~ G.Index (GM.BaseGrid gm p), k ~ G.Index (GM.BaseGrid gm v)) => SOM gm kp -> p -> [(k, v)] foo sp = GM.toList . GM.map (p `difference`) . sGridMap $ s bar :: (Pattern p, Ord v, v ~ Metric p) => [(k, v)] -> k bar ds = fst . minimumBy (comparing snd) $ ds wombat :: (Pattern p, Ord v, v ~ Metric p, GM.GridMap gm p, GM.GridMap gm v, k ~ G.Index (GM.BaseGrid gm p), k ~ G.Index (GM.BaseGrid gm v)) => SOM gm kp -> p -> (k, [(k, v)]) wombat sp = (bar diffs, diffs) where diffs = foo sp 

Here's the error:

 Ξ»> :l ../amy.hs [1 of 1] Compiling Main ( ../amy.hs, interpreted ) ../amy.hs:33:19: Could not deduce (v ~ Metric p0) from the context (Pattern p, Ord v, v ~ Metric p, GM.GridMap gm p, GM.GridMap gm v, k ~ G.Index (GM.BaseGrid gm p), k ~ G.Index (GM.BaseGrid gm v)) bound by the type signature for wombat :: (Pattern p, Ord v, v ~ Metric p, GM.GridMap gm p, GM.GridMap gm v, k ~ G.Index (GM.BaseGrid gm p), k ~ G.Index (GM.BaseGrid gm v)) => SOM gm kp -> p -> (k, [(k, v)]) at ../amy.hs:(30,10)-(32,40) `v' is a rigid type variable bound by the type signature for wombat :: (Pattern p, Ord v, v ~ Metric p, GM.GridMap gm p, GM.GridMap gm v, k ~ G.Index (GM.BaseGrid gm p), k ~ G.Index (GM.BaseGrid gm v)) => SOM gm kp -> p -> (k, [(k, v)]) at ../amy.hs:30:10 In the expression: bar diffs In the expression: (bar diffs, diffs) In an equation for `wombat': wombat sp = (bar diffs, diffs) where diffs = foo sp Failed, modules loaded: none. 
+4
source share
1 answer

This is a little hunch, but here goes:

p0 renamed from p to the signature bar .

 bar :: (Pattern p, Ord v, v ~ Metric p) => [(k, v)] -> k 

Here p occurs only to the left of => . Only k and v tags can be deduced from the call site. There can be many types of p that give the same result when specifying Metric , and the compiler cannot make the assumption that p in bar matches p in wombat , although Metric p is the same in both cases.

In this case, I would change the type signature to

 bar :: Ord v => [(k, v)] -> k 

like bar does not use any other restrictions.

If other restrictions are used in your real bar code, I would add a proxy argument (it could be of type p if I had a value of the corresponding type lying around like wombat , or from a -> p or p -> a and t .d.) to help type checking.

+6
source

All Articles