2017-05-24 1 views
3

나는 다음과 같은 유형이 있습니다지도 <'a, int>

type MultiSet<'a when 'a: comparison> = MSet of Map<'a, int> 

을하고 지금은 서명이 유형의 AF 맵 함수를 선언 할 : 나는 시도

('a -> 'b) -> Multiset<'a> -> Multiset<'b> when 'a : comparison and 'b : comparison 

:

let map m ms = 
    match ms with 
    | MSet s -> MSet (Map.map (fun key value -> m key) s) 

그러나 서명이 있습니다 :

('a -> int) -> Multiset<'a> -> Multiset<'a> when 'a : comparison 

처음 언급 한 기능 서명을 원할 때 구현에있어 잘못된 점이 있습니까?

답변

5

Map.map지도 이 아니라 키. 좋은 이유가 있습니다. 원래 키가 아닌 매핑 ​​된 키를 바로 연결할 수 없기 때문에 적합하지 않을 수 있습니다. 지옥, 그들은 심지어 Map.map 알고있는 누구나를 위해 유일하지 않을지도 모른다! 서로 다른 키를 사용하여지도를 구성하려면

, 당신은 다음에서 다른 Map를 생성, 변환, 순서로 분해해야합니다 :

let map m (MSet s) = 
    MSet (Map.ofSeq <| seq { for KeyValue (key, value) in s -> m key, value }) 

이 구현은 필요한 서명이 .

(또한, 당신이 match 할 필요가 없습니다 어떻게 알 당신이 바로 매개 변수 선언의 패턴을 포함 할 수 있습니다)

이 구현은 새 키의 유효성을 확인하는 데 아무것도하지 않는 것을을주의 : 예를 들어,을 그들은 고유하지 않은 것으로 밝혀지며, 일부는 사라질 것입니다. 나는 이것을 독자를위한 운동으로 남겨 둔다.

+1

좋은 답변입니다. 다수의 이전 키가 동일한 새 키에 매핑 될 때 수행 할 작업을 고려해 볼 가치가 있습니다 (카운트를 함께 추가하거나 오류를 발생 시키거나 임의의 값을 유지해야합니까?) – kvb

+0

이것은 좋은 지적입니다. 그러나 나는 그 답을 과부하하고 싶지 않았고, 즉각적인 문제를 해결했습니다. –

+0

위대한 답변, 정말 고마워요. – Alexander