2016-03-25 3 views
1

Мне нужна помощь, чтобы понять, как «< |» ведет себя на следующий код:Как работает обратный конвейер (т. Е. «<|»)?

Prop.forAll fiveAndThrees <| fun number -> 

    let actual = transform number 

    let expected = "FizzBuzz" 
    expected = actual 

В документации говорится следующее:

Передает результат выражения справа от функции на левой стороне (в обратном направлении оператора трубы).

5AndThrees не является функцией, а вместо этого значением, а в левой части оператора.

интерпретировать приведенное выше определение, как:

Возьмите вход под названием «номер» и кормить его в функцию «преобразования». Однако, если мы передаем результат выражения с правой стороны в функцию слева, то когда и как элемент ввода (т. Е. Число) действительно инициализируется?

Я просто не вижу его.

Полный тест состоит в следующем:

[<Fact>] 
let ``FizzBuzz.transform returns FizzBuzz``() = 
    let fiveAndThrees = Arb.generate<int> |> Gen.map ((*) (3 * 5)) 
              |> Arb.fromGen 

    Prop.forAll fiveAndThrees <| fun number -> 

     let actual = transform number 

     let expected = "FizzBuzz" 
     expected = actual 

Функция для проверки состоит в следующем:

let transform number = 
    match number % 3, number % 5 with 
    | 0, 0 -> "FizzBuzz" 
    | _, 0 -> "Buzz" 
    | 0, _ -> "Fizz" 
    | _ -> number.ToString() 
+1

См. Http://blog.ploeh.dk/2016/03/01/ad-hoc-arbitraries-now-with-pipes –

ответ

4

<| это оператор, который связывает менее сильно, чем применение функции, так что

Prop.forAll fiveAndThrees <| fun number -> ... 

разобран как

(Prop.forAll fiveAndThrees) <| fun number -> ... 

Prop.forAll принимает два параметра, в Arbitrary<T> и функции T -> Testable так Prop.forAll fiveAndThrees является функцией, в которой передаются правая рука.

+0

Спасибо Ли. Но если сначала выполняется выполнение правой части (то есть выражение), тогда как инициализируется вход (то есть число) в выражении? –

+3

@ScottNimrod - Выражение справа просто является функцией, так что это точно так же, как 'Prop.forAll fiveAndThrees (fun number -> ..)'. Я предполагаю, что использование '<|' является просто стилистическим выбором. – Lee

+0

Правильно, мое наиболее частое использование оператора '<|' - это когда я не хочу обертывать материал справа в дополнительных парадах. Например, 'raise <| CustomException (msg) 'vs' raise (CustomException (msg)) '. В этом случае было многострочное лямбда-выражение, которое немного неудобно обертывать в parens. –