f# - How do I copy a discriminated union case value? -
how copy discriminated union case value?
the following code has duplication:
let move (direction:direction) (checker:checker) = match checker | red xy -> red { xy x=2; y=2 } | black xy -> black { xy x=2; y=2 }
specifically, don't want specify type of checker set record value. hence, don't care if checker red or black. copy checker case value , update position.
i rather this:
let move (direction:direction) (checker:checker) = match checker | _ xy -> _ { xy x=2; y=2 }
here's test:
[<test>] let ``move checker``() = black { x=1; y=1 } |> move northeast |> should equal (black { x=2; y=2 })
appendix:
module test3 open nunit.framework open fsunit type position = { x:int; y:int } type checker = | red of position | black of position type direction = | northeast | northwest | southeast | southwest (* functions *) let move (direction:direction) (checker:checker) = match checker | red xy -> red { xy x=2; y=2 } | black xy -> black { xy x=2; y=2 } [<test>] let ``move checker``() = black { x=1; y=1 } |> move northeast |> should equal (black { x=2; y=2 })
the thing you're asking can't done in f# without reflection trickery.
here common sense explanation: rare union cases have exact same data under them. when case, indicates union cases "tags" used mark data, , should encoded "alongside" data, not "around" it. , since such union types rare exceptions, doesn't make sense invent language machinery support them.
this rationalization applies specific case nicely: color of checker "tag" should "next to" position, rather "wrapping" it. if define checker { pos: position; color: color }
, you'll able update position without touching color.
Comments
Post a Comment