Reputation: 32763
I'm using a union type with a single value for my ID to be type safe:
type PositionIdType = PositionId Int
Let's say I have a record:
type alias Position =
{ id : PositionIdType
, x : Float
, y : Float
}
I understand I can do a record destruct:
function : Position -> a
function { id } =
-- id is a PositionIdType
and similarly via assignment:
{ id } = Position (PositionId 99) 10 5
If I need to access the record too:
function : Position -> a
function ({ id } as position) =
-- id is a PositionIdType
-- position is a Position
And also destructing a single type:
function : PositionIdType -> a
function (PositionId id) =
-- id is an Int
Also via assignment:
(PositionId id) = (Position (PositionId 99) 10 5).id
Is it possible to join these two together? I have tried a few different ways without success, e.g.:
getIdInt ((PositionId { id }) as position) = id
getIdInt ({(PositionId id)} as position) = id
getIdInt (({PositionId id}) as position) = id
My current solution is to do it in a let
/in
block, which works just fine, but would be very nice to skip the let block if possible:
processPosition : Position -> a
processPosition ({id} as position) =
let
(PositionId id_) =
id
in
Http.post ("/position/" ++ id_) (positionEncoder position)
Upvotes: 1
Views: 756
Reputation: 6797
As of today (0.18.0
), destruncturing of nested Union Type value inside of the Record is impossible.
There's no info if this feature will ever land.
Here is a reference of record destructuring.
Tuple is the only Elm type, which allows nested destructuring.
nested ( x, ( y ) ) =
x + y
> nested ( 1, (1))
2 : number
Destructuring of Union Type is only possible with if..else
expression, case
expression or when it is passed directly as an argument to the function.
Here's what I would have done, if I were to write getIdInt
:
getIdInt : Position -> Int
getIdInt { id } =
case id of
PositionId val ->
val
main =
Position (PositionId 99) 10 5
|> getIdInt
|> toString
|> text -- 99
Upvotes: 1