F #을

2017-10-30 1 views
3

나는 기능이 시리즈, isMember, addElemcountries 있습니다F #을

let rec isMember x = function 
    | y::ys -> y=x || (isMember x ys) 
    | [] -> false 

let addElem x ys = if isMember x ys then ys else x::ys 

let rec countries = function 
    | []   -> [] 
    | (c1,c2)::m -> addElem c1 (addElem c2 (countries m)) 

내가 고차 함수를 사용하여 국가 재 작성 할를,하지만 난 완전히 확실하지 않다 방법 :

목록의 각 요소에 함수를 적용 할 예정이므로 제 생각에는 List.map과 관련이 있습니다.

let countriesHigherOrder m = 
    List.map (fun x -> addElem x m) 

답변

3

대신 List.map를 사용하여, 당신은 당신이 []로 초기화 ACCU로 List.fold를 사용하고 ACCU에 요소를 추가 할 수 있습니다.

let countriesHigherOrder m = 
    List.fold (fun acc (c1,c2) -> addElem c1 (addElem c2 acc)) [] m 

또는 addPair을 정의하여

가 : 간단한 목록으로 동시에 쌍의 목록을 평평하게하려면

let addPair (x, y) ys = 
    addElem x (addElem y ys) 


let countriesHigherOrder m = 
    List.fold (fun acc (c1,c2) -> addPair (c1, c2) acc) [] m 
+0

그것이 countriesHigherOrder m = List.fold하자 '대답 가능할 것이다 (재미 ACC (C1을, C2) -> addElem (C1, C2)는 ACC)] m'? – Khaine775

+2

예 가능합니다. 나는 addElem을 addPair로 바꿨다. addPair는 대소 문자 구분을 피하기 위해 addElem을 호출합니다. –

3

, 동일한 요소의 하나의 선두로부터 보존, 가장 짧은 코드는 것입니다 추가 연산자가 필요합니다.

let countries' m = 
    List.unzip m ||> (@) 
    |> Seq.distinct 
    |> Seq.toList 

, 다른 한편으로는, 당신이 당신의 이중 순환 방식의 독특한 주문을해야하는 경우, 2 요소의 목록에 튜플의 목록을 변환하고 사람들을 연결할 수 있습니다.

let countries'' m = 
    List.rev m 
    |> List.collect(fun (x,y) -> [y;x]) 
    |> Seq.distinct 
    |> Seq.toList 
    |> List.rev