F#에서 다른 유형의 배열의 구별 조합에서 타이핑 된 배열을 얻습니다.
-
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