1
votes

I have the following type:

type alias SelList a =
    { list : List a
    , selected : Maybe a
    }

A Sel(ectable)List a is a list of a from which I can possibly choose an element.

In my application, all my objects have an id : Int field, so I've defined this type alias :

type alias HasId r = { r | id : Int}

Now I would like a function eventually selecting an element in the list, I've tried :

select : Int -> SelList (HasId r)-> Maybe (SelList (HasId r))
select id sl = find (\x-> x.id ==id) sl.list &> \ el ->
               Just { sl | selected = el }

where (&>) = flip Maybe.andThen and find : (a -> Bool) -> List a -> Maybe a.

I've got the following message:

The type annotation for `select` says it always returns:

    Maybe (SelList (HasId r))

But the returned value (shown above) is a:

    Maybe { list : List (HasId r), selected : { r | id : Int } }

I'm confused because { r | id : Int } is the same than HasId, and then

{ list : List (HasId r), selected : HasId r }

is the same than SelList (HasId r). Why the compiler can not figure out that the types match?

1

1 Answers

1
votes

The compiler's error is 90% of the way there, but I think mixing type aliases and records makes it harder to figure out what's wrong. (Future versions of Elm are going to improve this).

If it was a record and not a Maybe record, the compiler would tell you something like "I see a problem with the selected field`". Does that help?

Spoiler: The SelList type has a selected : Maybe a, but select returns selected : a