2009-05-23 3 views
7

이 예제 코드를 가지고재귀 람다

let listToString (lst:list<'a>) = ;;' prettify fix 

    let rec inner (lst:list<'a>) buffer = ;;' prettify fix 
     match List.length lst with 
     | 0 -> buffer 
     | _ -> inner (List.tl lst) (buffer + ((List.hd lst).ToString())) 

    inner lst "" 

이 내가 F 번호에 걸쳐 계속오고 일반적인 패턴은 (는 순간 끔찍하게 비효율적 인 무시), 나는 자신을 재귀 내부 기능이 필요합니다 어떤 가치를 넘어서 - 나는이 함수가 한 번만 필요하다. 어떤 식 으로든 자기 자신에게서 람다를 호출 할 수있는 방법이 있는가? 나는이 같은보고 코드를 싶습니다

let listToString2 (lst:list<'a>) = ;;' prettify fix 

    (fun 
     (lst:list<'a>) buffer -> match List.length lst with ;;' prettify fix 
           | 0 -> buffer 
           | _ -> ##RECURSE## (List.tl lst) (buffer + ((List.hd lst).ToString())) 
    ) lst "" 

을하지만 예상대로 내가 ## 재귀 ##

답변

17
을 어디다 필요한 자체 내에서 익명 함수를 참조 할 수있는 방법은 없습니다

예, y-combinators (또는 fixed-point combinators)을 사용하는 것이 가능합니다. 예는 :

let rec fix f x = f (fix f) x 

let fact f = function 
| 0 -> 1 
| x -> x * f (x-1) 


let _ = (fix fact) 5 (* evaluates to "120" *) 

나는 F 번호에 대한 기사를 모르지만이 haskell entry도 도움이 될 수 있습니다.

하지만 대안이 있다면 사용하지 않겠습니다. 이해하기가 어렵습니다.

코드 (여기에서 유형 주석을 생략)는 표준 구조이며 훨씬 표현력이 뛰어납니다.

let listToString lst = 

    let rec loop acc = function 
     | [] -> acc 
     | x::xs -> loop (acc^(string x)) xs 

    loop "" lst 
1

주 당신은 당신이 기술적으로 당신이 그것을 이름을 지정하는 것이 합리적 이유입니다, 두 번 이름으로 그것을 참조, 한 번만 기능을 사용하여 말을하지만.