2011-04-26 5 views
2

배열의 값이 true와 일치하면 배열을 통해 int의 목록 (인덱스 값)을 반환하고 싶습니다.Ocaml이 재귀 함수에서리스트를 반환했습니다.

배열은 참/거짓 값의 부울 배열입니다.

let get_elements (i:int)(b:bool) : int = 
    if b = true then (i::l) 
    else (()) 
;; 

let rec true_list (b: bool array) : int list = 
    (fun i l -> get_elements i l) 
;; 

구문은 내 코드에 대한 잘못과 나는 단지 배열에 해당하는 요소의 인덱스를 반환 할 ints.I의 목록을 반환하는 방법을 정확하게에 혼란 스러워요.

답변

3

get_elements에서 'l'을 참조하지만 해당 함수의 범위에 속하지 않습니다.

: 당신은 오히려이 청소기 (일반적으로 좋은 생각입니다) 심판을 피하려는 경우,

boolarray = [|true; false; true; false; false; true|] ;; 
type ilist = (int list) ref ;; 
let intlist() : ilist = ref [] ;; 
let push (l: ilist) (x: int) : unit = l := x::(!l) ;; 
let lst = intlist() ;; 
Array.iteri (fun i b -> if b = true then (push lst i)) boolarray ;; 
!lst ;; (* => int list = [5; 2; 0] *) 

또는 :

여기에 정수 목록에 심판을 사용하여 접근 (변경 가능한 목록)의

let get_true_list (b: bool array) : int list = 
    let rec aux i lst =  
    if (i = Array.length b) then lst else 
     (if b.(i) = true then (aux (i+1) (i::lst)) else (aux (i+1) lst)) in 
    aux 0 [] ;; 
(* using boolarray defined above *) 
get_true_list boolarray ;; (* => int list = [5; 2; 0] *) 
+3

또는과 [배터리] (http://batteries.forge.ocamlcore.org/),'Array.fold_lefti (재미있는 리 (IB) -> 다음에 b 내가 리튬 다른 리튬을 :: 경우) []' . 또한, 당신의 ref 구조의 예에서는 함수를 ref로 캡슐화해야한다고 생각합니다. 왜냐하면 여기에서는 항상 ref를 전역으로 가지고 있기 때문에, 필요한 것보다 훨씬 더 추악하기 때문입니다. – gasche

+0

참조를 포함하지 않은 답변으로 답변을 바꾸어서 기쁘게 생각합니다. – nlucaroni

2
 
I present an example which does not use state, avoids the 'if then else' construct making it easier to read and verify. 

let mylist = [| true; false; false; true; false; true |] in 
let get_true_indexes arr = 
    let a = Array.to_list arr in 
    let rec aux lst i acc = match lst with 
     | []     -> List.rev acc 
     | h::t when h = true -> aux t (i+1) (i::acc) 
     | h::t    -> aux t (i+1) acc 
    in 
    aux a 0 [] 
in 
get_true_indexes mylist 
관련 문제