지도

2012-06-03 8 views
1

은 이제 나는 차별 노동 조합 있다고 가정 해 봅시다 지도의 각 구성원에 대한 비용을 포함 :지도

[(Smithy, 4); (Cellar, 6); (Chapel, 2)] 

이게 가능합니까? 내가 좋아하는 뭔가를 할 수 있도록하고 싶습니다 :

List.zip (allValues f) (List.map getCost (allValues f)) |> Map.ofList 

This question 도움이됩니다를하지만 내가 필요 꽤 게 아니에요; 나는 그들의 속성을 검사하는 대신에 메모리에있는 노동 조합 멤버들에게 접근 할 수 있기를 원한다.

내가 이것을하고 싶은 이유는 게임에서 모든 다른 유형의 카드를 나타내는 차별화 된 조합과 각 카드의 몇 개가 처음에 있어야하는지 알려주는 기능입니다. 카운트에 대한 카드의 초기 매핑을 쉽게 생성 할 수 있습니다. 이 작업을 수행하는 더 좋은 방법이 있습니까?

+1

당신이 무엇을 할 것이다 당신의 차별 노동 조합 사례 중 하나가 string'의'T 있다면? 그런 다음 생성자를 찾아야하고'string '을'getCost'에서 사용할 수 있습니다. 이 시점에서 상황은 매우 복잡해집니다. 아마도 이것을 사용하려고하는 것을 우리에게 말할 수 있습니까? –

+1

나는 당신이 무엇을 요구하고 있는지 이해하지 못한다. 그럼에도 불구하고 나는 F #을 사용하여 Dominion에 관한 블로그/앱을 볼 것을 고대하고있다. :) – Brian

답변

5

F # Reflection을 사용하여 차별화 된 가능한 모든 케이스의 목록을 얻을 수 있지만 Reflection의 단점을 이해하는 것이 중요합니다. 조심스럽게 사용하지 않으면 쉽게 디자인이 좋지 않을 수 있습니다 (더 간단하고 세련 될 수 있음). 기능적 솔루션), 효율성이 떨어집니다 (모든 사례를 한 번만 입력하면됩니다).

다음 getAllValues 기능은 모든 경우를 얻을 수 - 당신이 경우에 몇 가지 인수를 전달하고 싶었 사례 중 누구도 어떤 값 (! 즉 Smithy of string가 작동하지 않습니다)에 저장 없다고 가정, 당신은 두 번째에 박스 값을 전달해야 MakeUnion의 인수 : 여기

open Microsoft.FSharp.Reflection 

let getAllValues<'T>() : 'T list = 
    let cases = FSharpType.GetUnionCases(typeof<'T>) 
    [ for c in cases -> unbox (FSharpValue.MakeUnion(c, [| |])) ] 

이 시나리오에서 함수를 사용하는 예는 다음과 같습니다

type card = Smithy | Cellar | Chapel 

let initialCardCount = function 
    | Smithy -> 4 
    | Cellar -> 6 
    | Chapel -> 2 

let values = getAllValues<card>() 
List.zip values (List.map initialCardCount values)