I'm doing the Elm exercises in Exercism again and there's a thing unclear to me so far. How does the "as" destructuring work? In the beginning I didn't understand anything. After read Yang Wei's Elm destructuring (or pattern matching) cheatsheet, more specifically this part:
myRecord = { x = 1, y = 2, z = 3}
computeSomething ({x, y} as wholeRecord) =
-- x and y refer to the x and y fields of the passed in record
-- wholeRecord is the complete record
-- i.e. x and wholeRecord.x refer to the same field
-- but z is only accessible as wholeRecord.z
A lot of things became more cleat to me. The problem happened when I tried to make it by myself. So, the Ticket, Please! problem imports three types, called Ticket, Status and User and I should write a functions that receives a ticket and an user and returns a modified ticket, as the given example:
assignTicketTo (User "Danny")
(Ticket
{ status = New
, createdBy = ( User "Jesse", 3 )
, assignedTo = Just (User "Alice")
, comments = [ ( User "Jesse", "I've been waiting for 6 months!!" ) ]
}
)
-- => Ticket
-- { status = InProgress
-- , createdBy = ( User "Jesse", 3 )
-- , assignedTo = Just (User "Danny")
-- , comments = [ ( User "Jesse", "I've been waiting for 6 months!!" ) ]
-- }
The big problem comes here, because after descruture the Ticket variable and use as to attribute it to a different variable (as below), the language tells me that the new variable has a different type, i.e. it is not a Ticket.
assignTicketTo : User -> Ticket -> Ticket
assignTicketTo user ({ status, assignedTo } as ticket) =
if (status == New) then
{ ticket | status = InProgress, assignedTo = Just user }
else
ticket
What am I doing wrong? I read the answer about Type mismatch when trying to destructure type in Elm, but the only thing that I can imagine I could possibly be doing wrong, the desctructuring, is not correct either:
assignTicketTo : User -> Ticket -> Ticket
assignTicketTo user (Ticket { status, assignedTo } as ticket) =
if (status == New) then
{ ticket | status = InProgress, assignedTo = Just user }
else
ticket
Edit: The error messages are:
This is not a record, so it has no fields to update!
45| Ticket { ticket | status = InProgress, assignedTo = Just user }
^^^^^^
This `ticket` value is a:
Ticket
But I need a record!
and
The 2nd argument to `assignTicketTo` is weird.
43| assignTicketTo user ({ status, assignedTo } as ticket) =
^^^^^^^^^^^^^^^^^^^^^^
The argument is a pattern that matches record values of type:
{ c | assignedTo : a, status : b }
But the type annotation on `assignTicketTo` says the 2nd argument should be:
Ticket