Why can't I simplify this iteration through the list of members of the discriminatory union?

Iteration is often required (using a map, iterator, or fold) through a set of heterogeneous objects (of different types). One way to deal with this is to create a discriminatory alliance that allows you to create a list with objects appropriately transformed into DU affairs. The following code does this with a simple example:

type MYDU = | X1 of int
            | X2 of float
            | X3 of string

let bar (y: MYDU) =
    match y with
    | X1 x -> printfn "%A" x  
    | X2 x -> printfn "%A" x
    | X3 x -> printfn "%A" x

[X1(1); X2(2.0); X3("3"); X1(4)]
|> List.map bar |> ignore

This code works fine and prints

1
2.0
"3"
4

Fine! But I wonder if the challenge can be repeated printfn. I tried the following and it does not compile:

let baz (y: MYDU) =
    match y with
    | X1 x | X2 x | X3 x -> printfn "%A" x // red squiggly line under X1 x

The compiler displays this message:

This expression was expected to have type 'int' but here has type 'float'

I suspect it is possible to avoid repetition, but I have to make a basic mistake. Any suggestions?

+4
source share
3

, , F #.

, ( ). x , .

( DU, , , ), , .

+3

, . - :)

type MYDU = 
  | X1 of int
  | X2 of float
  | X3 of string

let bar y =
    let myStr = 
      match y with
      | X1 x -> string x  
      | X2 x -> string x
      | X3 x -> x
    printfn "%s" myStr

bar (X1 5)
+2

"" obj. .NET System.Object: " .NET Framework". , obj.

, , . F # . , .

printfn "%A" , obj -> unit. , , , . , box:

let (|Box|) x = box x

:

let printMyDu myDu =
    match myDu with
    | X1 (Box x)
    | X2 (Box x)
    | X3 (Box x) -> printfn "%A" x

, , , . , - , , , , F #. x, , .

+2
source

Source: https://habr.com/ru/post/1685389/


All Articles