2012-05-29 3 views
3

변수 al : 'a list, 함수 a_to_b : 'a -> 'b 및 함수 score : 'b -> int을 선언했습니다. 다음 코드에서 let bl = List.map a_to_b al in ...bl : 'b list을 정의합니다.대응하는 2 세트의 유형을 결정하십시오

let find_best (bl : 'b list) : 'b = 
    let score_best, b_best = List.fold_left 
    (fun (score_old, b_old) b_new -> 
     let score_new = score b_new in 
     if score_old < score_new then 
      (score_new, b_new) else 
      (score_old, b_old)) 
    (score (List.hd bl), List.hd bl) bl in 
    b_best 

let bl = List.map a_to_b al in 
find_best bl 

이 코드 조각은 score가 큰하다는 b_best 등을 찾습니다. 하지만 내 요구 사항 중 하나는 a_bestb_best을 통해 a_to_b을 생성하고 어떤 방식 으로든 알고 싶어한다는 것입니다. 예를 들어, b_bestbl의 네 번째 요소 인 경우, 제 4 번째 엘름을 al으로 생각합니다.

더 많은 매개 변수를 함수 find_best에 추가하고 싶지 않습니다. 내 질문은 대신 array을 사용하여 a_bestb_best에서 쉽게 추적 할 수 있도록 albl 유형을 정의하는 일반적인 방법이 있습니까? 또는에 array 변환 후 list로 변환? 난 그냥 쌍의 목록을 가지고 한 쌍을 반환 b_best을 정의하는 것

let abl = List.combine bl al in (* ('b * 'a) list *) 
let a_best = List.assoc b_best abl (* returns the value associated to b_best *) 
+0

그런데'find_best' 함수의 정확한 이름은'argmax'입니다 : http://en.wikipedia.org/wiki/Arg_max –

답변

3

당신은 그런 일을 할 수 있습니다.

let find_best (bl : ('b * 'a) list) : 'b * 'a = 
    let score_best, ba_best = List.fold_left 
    (fun (score_old, (b_old, a_old)) (b_new, a_new) -> 
     let score_new = score b_new in 
     if score_old < score_new then 
      (score_new, (b_new, a_new)) else 
      (score_old, (b_old, a_old))) 
    (score (List.hd bl), List.hd bl) bl in 
    ba_best 

(. 또는 당신은이 목록을 가지고 그것을 정의 할 수 있습니다, 그러나 이것은 더 적은 당신이 요구하는지처럼 보인다)

: 그것은 쌍의 두 번째 요소에 다형성 것 당신이 말한 제약 하에서, find_bestal에 접근 할 수 없으므로, 인덱스를 반환하고 나중에 에서 값을 검색하기 위해 List.nth을 사용해야하는 것처럼 보입니다. 긴 목록을 사용하여이 작업을 많이해야하는 경우 List.nth이 너무 느려서 al에 배열을 사용할 수 있습니다.

+0

이것은'b' 타입이'= '를 지원한다고 가정합니다. '. 'List.assq'가 더 나은 옵션 일 수 있습니다. –

2

많은 경우 :

관련 문제