1

Given the code such as (imports are stripped for brevity):

fn: List a -> List a -> Bool
fn x y =
  x < y

main =
  text (toString(fn [1,1] [1,2]))

I got quite a strange error:

The type annotation for `fn` does not match its definition.

15| fn: List a -> List a -> Bool
        ^^^^^^^^^^^^^^^^^^^^^^^^
The type annotation is saying:

    List a -> List a -> Bool

But I am inferring that the definition has this type:

    List a -> List a -> Bool

Without the type annotation or with type annotation but using == instead of < everything works OK. Is this a bug in elm compiler or am I doing something wrong?

I used online editor at http://elm-lang.org/try

Tomas Kulich
  • 14,388
  • 4
  • 30
  • 35
  • It seems you need to mark `a` as `comparable`. This type declaration typechecks `fn: List comparable -> List comparable -> Bool`. I think it is all because you can compare list of comparable items. But it is just a speculation since I'm new to elm. :) – Yury Tarabanko Jun 29 '16 at 11:27
  • Huh, that really solves it :) But.. what does the comparable actually do? I saw this keyword already but I thought that in this context, this is just a placeholder to denote the variable which is as good as `a` which I used. – Tomas Kulich Jun 29 '16 at 11:32
  • "what does the comparable actually do" I don't know. Some sort of a built-in type constrain I guess. I'm new to elm that's why I've posted it as a comment waiting for someone who knows more :) – Yury Tarabanko Jun 29 '16 at 11:35
  • Ok, so it seems 'comparable' really is a type constraint: http://stackoverflow.com/questions/31885622/what-does-comparable-mean-in-elm – Tomas Kulich Jun 29 '16 at 11:40

1 Answers1

1

This is a problem with the compiler, it's been reported here. It looks like y'all have already figured out what comparable does based on the comments but for those who prefer to skip to the answers:

There are a couple of "magic" type variables that can be used in type annotations to constrain the types of things that can be passed in. They are:

  • comparable (Int, Float, Char, String, and Lists and n-tuples of any of those): anything that operators like (<) will accept, as you've discovered
  • appendable (String, List, Text): anything that the (++) operator will accept
  • number (Float, Int): anything that operators like (+) and (-) will accept
lukewestby
  • 1,207
  • 8
  • 15