Strange Pattern Match Error

Hello.

evaluate_individual :: StdGen → Weight → Weight
evaluate_individual gen (Weight ((w, x, y, z), f))
  = let (fitness, _) = random gen :: (Float, StdGen)
     in Weight ((w, x, y, z), fitness)

You are missing the Weight constructor in the pattern matching.

The compiler is trying to match (Weight ((w, x, y, z), f)) which is type Weight, with ((w, x, y, z), f) which is type ((Float, Float, Float, Float), b0).

It’s a type like a0, a1, b0, b1: an automatically named type that the compiler gives to values with the most generic type (because they couldn’t infer anything else). All values have a type.
You will notice that the compiler attributed w, x, y, z as Float, Float, Float, Float. and that’s because it inferred it from Weight ((w, x, y, z), fitness) inside the let.
Since you were using those variables as Float, it makes sense they are Float! And it typechecks so those are Float.

Another thing:

data Weight = Weight ((Float, Float, Float, Float), Float) deriving Show

Generates two things.
A type: Weight.
A constructor: Weight :: ((Float, Float, Float, Float), Float) -> Weight.
You can rename them if it confuses you, to something like this:

data Weight = MkWeight ((Float, Float, Float, Float), Float) deriving Show

Those are different things but Haskell allows you to name them the same because they appear in different places (function signatures vs patterns and function bodies) so the ambiguity can be solved.

2 Likes