2016-09-13 1 views
1

제목이 잘못되었으므로이 질문을 설명하는 방법을 모릅니다. 몇 가지 코드 예제를 통해고급 함수 C#의 Lambda/LINQ 식과의 혼동

오전 읽고 다음과 같은 리턴 기능을 통해 혼란 스러워요 :

Func<Func<int , bool>, Func<int , int>, Func<int , int>> Loop = null ; 
Loop = (c , f) => n => c(n) ? Loop(c , f) (f (n)): n; 
Func<int , int> w = Loop(n => n < 10 , n => n + 2); 
var r = w(2); 
var s = w(3); 
Console . WriteLine ("{0} {1}" , r , s); 

내가 C (n)이 true로 평가되면이 기능은 루프를 반환하는 것을 이해하지만, 이해가 안 돼요 루프 (c, f) (f (n))가 어떻게 평가되는지 - 둘 다 루프로 다시 전달 되는가? Linqpad에서 덤프를 실행하려고 시도했지만 그 비트가 어떻게 실행되고 있는지 알 수 없습니다.

도움이 될 것입니다, 아마도 이것은 바보 같은 질문입니다!

답변

4

이해를 시도하는 한 가지 방법은 작은 시작입니다. 기본 루프 1 -10 증가 +1. 아주 간단

Func<int,int> basicLoop = null; 
basicLoop = n => n < 10 ? basicLoop(n+1) : n; 

-basicLoop 매개 변수에 n 수익을 기반으로 기능입니다 n 또는 증분 매개 변수를 사용하여 자신을 호출 (N> = 10). 그래서 basicLoop(8)과 같이 계산된다 : 그래서

  • basicLoop(9) 9 < (10) 결과를 얻을 수 basicLoop(8+1)를 호출

    • basicLoop(8) 8 < 10, 그래서 반환 n 있도록
    • basicLoop(10) 10 == 10 결과를 얻으려면 basicLoop(9+1)를 호출하는 는 10입니다.
    • basicLoop(9) 결과가 10 () 인 경우이를 반환합니다.
    • basicLoop(8) 결과 10 (basicLoop(9)에서)을 반환하고이를 반환합니다.

    이제 매개 변수로 조건을 루프에 전달하려고합니다.즉, "루프"Func은 반복 될 때마다 해당 조건을 전달해야합니다.

    해당 유형의 유형이 분명합니다 (n<10과 유사) - Func<int, bool>입니다. 이제 우리는 Func<int,bool>을 인수로 취하여 원래 값인 basicLoop과 동일한 값을 반환합니다. 따라서 그것은 하나 개의 인수 및 하나 개의 결과의 Func 될 것입니다 :

    Func<Func<int, bool>, Func<int,int>> condLoop = null; 
    

    condLoop 한 인수의 함수 - 정의 할 때 우리가 인수 걸릴 : condLoop = (condition) => ...합니다.

    원래 basicLoop의 조건을 바꿔야합니다. n => n < 10 ? ...n => condition(n) ? ...이됩니다.

    마지막 부분은 basicLoop(n+1)을 대체합니다. 여기에 조건을 전달할 때 basicLoop과 동일한 값을 반환하는 condLoop 함수가 있습니다. 다행히도 우리의 조건은 반복 사이에 바뀌지 않으며 이미 가지고 있습니다. condLoop(condition)basicLoop과 같습니다. 모두 함께 그것을 얻기 :

    condLoop = (condition) => 
        n => condition(n) ? 
         condLoop(condition) (n + 1) : 
         n; 
    

    를 호출 condLoop(x => x < 5)(4)

    • condLoop(x => x < 5)(4)을 통해 추적 - 조건은 x => x < 5이고, n = 4 그렇게 할 때 condition(4)라고 X = 4, 4 < 5는 사실이다 - 같은과 condLoop를 호출 조건을 증가시키고 결과를 얻기 위해 n을 condLoop(x => x < 5)(4 + 1) 증가 시켰습니다.
    • condLoop(x => x < 5)(5) - 조건은 x => x < 5이고 n은 5이므로 condition(5)이 x = 5 일 때, 이제 conditionincrement을 통과해야 모든 반복에 - 유사한 논리 값을 증가 기능을 추가로 condLoop(x => x < 5)(5)

    의 결과로 5를 반환 - 5

  • 다시 condLoop(x => x < 5)(4)하는 것입니다 n를 반환 - 5 < 5 거짓 기능 (cf 원래 게시물).

  • +0

    아! 그래서 Loop (c, f) (f (n)) 문법은 Loop (c, f)를 호출하기위한 조건으로 f (n)을 호출하고 있는가? 나는 그 구문이 어떻게 작동 하는지를 고민하고있다. – user3431504

    +0

    나는 그것을 "recall Loop"이라고 부르지 않을 것입니다 - 아마도 "condition"을 "다음 반복의 값"으로 사용했을 것입니다 ...'loop (c, f)'는'basicLoop '하나. 'f (n)'은'f' 함수를 호출하는 것입니다. ... combine -'Loop (c, f) (f (n))'는'Loop (c, f)'를 호출하고 결과는'f n)'... 또는 다른 말로하면 - 루프의 다음 반복시에 'n'이 있어야합니다 ... –

    +0

    각 호출을 기록하는 함수를 조건'n => {Console.WriteLine ("Condition {0} ", n); n <10;}'을 반환하고 얼마 동안 출력을 응시합니다 ... –

    1

    C#의 익명 대리자 선언 구문이 혼동을 불러 오므로 F #의 함수 형식 구문으로 다시 작성하겠습니다.

    (int -> bool) -> (int -> int) -> (int -> int) 
    

    그래서이 함수는 두 가지 함수를 사용하여 함수를 반환하는 함수입니다. 받아들이는 첫 번째 함수는 술어이고, 두 번째 함수는지도이며, 마지막으로 int를 반환하는 함수를 반환합니다.

    Loop = (c , f) => n => c(n) ? Loop(c , f) (f (n)): n; 
    

    위 서명의 구현. 예상대로 두 매개 변수를 c 및 f로 사용합니다. 우리는 함수를 반환 할 것으로 예상하고, 여기있다 : 나는 루프를 상상할 수

    n => c(n) ? Loop(c,f) (f (n)) : n; 
    

    (C, F) (F (N)) 부분이 가장 당신에게 던지고있다. Loop를 호출 한 결과는 정수를 받아들이고 정수를 반환하는 함수입니다. n은 정수이고, f는 정수를 취하여 정수를 반환하는 함수입니다. w의 조건에서이 정수를 2 씩 증가시킵니다. 따라서 첫 번째 예제에서와 같이 n이 2 인 경우 f (n), 2 + 2의 결과를 새 n으로 전달합니다. c (n)이 참일 때마다 n을 10 이상이 될 때까지 매번 2 씩 증가시키면서 계속 반복합니다.

    +0

    정말 도움이 되긴하지만, 구문에 뭔가 빠져있는 것 같아요. 루프 (c, f) (f (n))와 함께, 나는 루프가 어떻게 멈추는 지 이해하지 못한다. - 루프 (c, f)를 리콜하기 전에 (f 값이 변경 되었습니까? – user3431504

    +0

    'f (n)'은 3, 5, 7, 9, 11, ..과 같이 증가 할 때마다 int 값입니다. (f ='x => x + 2') . 그리고 결국 조건은'? :'의 마지막 부분의 평가를 트리거하기 위해 false가되어 현재 값을 반환함으로써 재귀를 멈춘다. –

    +0

    함수'f'는'w'의 숫자에서 숫자를 취하여 2를 더합니다. 'w'의 항에서'c' 함수는 입력 된 숫자가 10보다 작 으면 참을 반환합니다.'Loop (c, f)'는'n => c (n)? 루프 (c, f) (f (n)) : n;'당신은 단계적으로 생각할 수 있습니다. 입력 된 첫 번째 값은 2. 2 <10이므로 c (n)만큼 검사를 통과합니다. f (n) == f (2) == 2 + 2 == 4. 루프 (c, f) =='n => c (n)? 루프 (c, f) (f (n)) : n;'. 루프 (c, f) (f (n)) =='루프 (c, f) (4)'=='(n => c (n)) : n) (4)'4는 10보다 작기 때문에'Loop (c, f) (6)'과 같은'Loop (c, f) (f (4))'로 간다. 이것을 계속 확대 할 수 있습니다. –

    1

    는 "나는 C (n)이 true로 평가되면이 기능은 루프를 반환하는 것을 이해하지만, 루프 (C를, f는) (F (N)) 평가 방법 이해가 안 돼요"- 기능하지 않습니다 Loop을 반환하십시오. 기능 Loop이며, 그것은 Func<int, int>을 반환합니다.

    그래서 Loop 입력으로 두 가지 기능을 얻어 제 3 함수를 리턴하는 함수이다. 이 표시는 Func<Func<int , bool>, Func<int , int>, Func<int , int>>입니다. Loop 실제로 두 번째 줄에 정의 될 때

    이제, 그것은 자신을 재귀 적으로 호출 할 수있는 제 라인 Loop = null되도록.

    그런 다음 Loop은 기본적으로 기능 n => c(n) ? Loop(c, f)(f(n)) : n를 반환하는 함수이다.즉 Loop는, 미래에 n 주어진 함수를 반환이 falsec(n)truenLoop(c, f)(f(n))을 반환 할 것이다;

    w 다음 파라미터 n => n < 10 & n => n + 2Loop 때의 리턴 함수이다.

    그래서, Loop에 사람들을 대체이 같은 w을 정의 할 수 있습니다 :

    이제
    Func<int, int> w = null; 
    w = n => n < 10 ? w(n + 2) : n; 
    

    즉,이 같이 다시 쓸 수있다 :

    int w(int n) 
    { 
        while (n < 10) 
        { 
         n += 2; 
        } 
        return n; 
    } 
    

    를 잘하면 그 진행이 쉽게 볼 수 .