F#에서 다른 유형의 배열의 구별 조합에서 타이핑 된 배열을 얻습니다.

StackOverflow https://stackoverflow.com/questions/1939113

  •  20-09-2019
  •  | 
  •  

문제

다른 유형의 배열에 대한 식별 조합이있는 경우 어떻게 '실제'유형으로 변환 할 수 있습니까?

type ItemStuff = 
   | Colors of string[]
   | Sizes of int[]

let foo = Sizes [|1;2;3|]

foo의 가치를 얻을 때 위의 것을 실행 한 후 다음을 본다.

val foo : ItemStuff = Sizes [|1;2;3|]

Foo에서 실제 int 배열을 얻으려면 어떻게해야합니까? 내가 같은 것에 액세스 할 수있는 구문이 빠졌습니까?foo.[2]? Foo를 통해 열거 할 수 없으므로지도를 사용할 수 없었습니다. ItemStuff에 대한 멤버를 쓸 수있는 각 유형의 배열에 대해 올바르게 입력 된 배열을 반환 할 수 있지만, 그게 옳지 않은 것 같지 않습니까?

여기서 가장 좋은 접근 방식은 무엇입니까?

여기에 내가 한 일이 있습니다. 더 나은 방법에 대한 아이디어가 있습니까?

type ItemProp =
| Colors of string[]
| Sizes of int[]
| Quants of int[]
member this.GetColors() =
   match this with
   | Colors (stringArray) ->
       stringArray
   | _ -> null
member this.GetIntArr() =
   match this with
   | Sizes (intArray) | Quants (intArray) ->
       intArray
   |_ -> null

foo.GetIntArr()
도움이 되었습니까?

해결책

Foo에서 실제 int 배열을 얻으려면 어떻게해야합니까?

그것이 그 이후의 실제 문제입니다 foo 방금 유형이 있다고합니다 ItemStuff. 그래서 필요하지 않습니다 a Sizes- 전혀 값 - 아마도 가능할 수 있습니다 Colors 또한.

따라서 귀하의 프로그램은 여기에서 결정해야합니다

let getIntArray = function
    | Sizes arr -> arr
    | Colors _  -> failwith "Given value doesn't contain an int array`

getIntArray foo 제대로 작동하지만 getIntArray (Colors [||]) 실패하지만 유형 수준에서 둘 다 유효합니다.

작업이 성공할 것이라고 완전히 확신하면 패턴 매칭을 직접 사용할 수 있습니다.

let getIntArray (Sizes arr) = arr

다른 팁

일반적으로 패턴 매칭을 사용합니다. ItemStuff 색상이나 크기를 보유합니다. 당신이 확실히 알고 있다면 Sizes 예, 다음과 같은 작업을 수행 할 수 있습니다.

let (Sizes arr) = foo

배열을 뒤로 당기려면.

실제로 중 하나/또는 시나리오 (색상 또는 크기)를 나타내지 않는 경우 레코드 유형 여기:

type ItemStuff = 
    { Colors : string[];
      Sizes : int[] } with
    static member Default = { Colors = [||]; Sizes = [||] }

let foo = { ItemStuff.Default with Sizes = [|1;2;3|] }
printfn "%A" foo.Colors    // [||]
printfn "%A" foo.Sizes     // [|1; 2; 3|]
printfn "%d" foo.Sizes.[2] // 3

차별화 된 연합이 Sizes.

let getIntArray item =
    match item with
    | Sizes(i) -> Some(i)
    | _        -> None

그러나 F#의 마지막에 함수는 항상 입력 데이터 유형을 출력 데이터 유형으로 변환하거나 함수는 부작용을 만듭니다 (화면에 무언가를 인쇄하거나 데이터를 배열에 삽입).

예를 들어, 인쇄하고 싶다면 Sizes (또는 그것이 a Colors) 그 목적을 위해 새로운 기능을 작성하는 것이 더 짧습니다.

let printSizes item =
    match item with
    | Sizes(i) -> printfn "%A" i
    | _        -> ()

대신에:

let getIntArray item =
    match item with
    | Sizes(i) -> Some(i)
    | _        -> None

let res = getIntArray foo

(function | Some(i) -> printfn "%A" i | _ -> ()) res
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top