Search code examples
elm

What does comparable mean in Elm?


I'm having trouble understanding what exactly a comparable is in Elm. Elm seems as confused as I am.

On the REPL:

> f1 = (<)
<function> : comparable -> comparable -> Bool

So f1 accepts comparables.

> "a"
"a" : String
> f1 "a" "b"
True : Bool

So it seems String is comparable.

> f2 = (<) 1
<function> : comparable -> Bool

So f2 accepts a comparable.

> f2 "a"
As I infer the type of values flowing through your program, I see a conflict
between these two types:

    comparable

    String

So String is and is not comparable?
Why is the type of f2 not number -> Bool? What other comparables can f2 accept?


Solution

  • Normally when you see a type variable in a type in Elm, this variable is unconstrained. When you then supply something of a specific type, the variable gets replaced by that specific type:

    -- says you have a function:
    foo : a -> a -> a -> Int
    -- then once you give an value with an actual type to foo, all occurences of `a` are replaced by that type:
    value : Float
    foo value : Float -> Float -> Int
    

    comparable is a type variable with a built-in special meaning. That meaning is that it will only match against "comparable" types, like Int, String and a few others. But otherwise it should behave the same. So I think there is a little bug in the type system, given that you get:

    > f2 "a"
    As I infer the type of values flowing through your program, I see a conflict
    between these two types:
    
        comparable
    
        String
    

    If the bug weren't there, you would get:

    > f2 "a"
    As I infer the type of values flowing through your program, I see a conflict
    between these two types:
    
        Int
    
        String
    

    EDIT: I opened an issue for this bug