F # - вложенные трубопроводы - PullRequest
0 голосов
/ 12 марта 2011

Я сейчас читаю книгу "Функциональное программирование в реальном мире" и задаюсь вопросом, как я могу написать что-то вроде:

let numbers = [ 1 .. 10 ]
let isOdd(n) = (n%2 = 1)
let square(n) = n * n

let myList = 
    numbers 
    |> List.map square 
        |> List.iter(printfn "%d")
    |> List.filter isOdd 
        |> List.iter(printfn "%d")

Код, который я выложил, потерпит неудачу после First List.iter () с сообщением:

Несоответствие типов. Ожидается блок -> 'a, но учитывая a' список b -> 'b список Тип «блок» не соответствует типу '' список ''

Как я могу сделать что-то как выше (только где это будет работать)?

1 Ответ

3 голосов
/ 12 марта 2011

Вы можете использовать List.map вместо List.iter и возвращать элементы без изменений.Вы бы перестроили список:

let myList =
    numbers
    |> List.map square
    |> List.map (fun x -> printfn "%d" x; x)
    |> List.filter isOdd
    |> List.map (fun x -> printfn "%d" x; x)

Другой способ, вместо того, чтобы хранить отдельно каждый элемент, это сохранить весь список как параметр функции:

let myList =
    numbers
    |> List.map square
    |> (fun xs -> List.iter (printfn "%d") xs; xs)
    |> List.filter isOdd
    |> (fun xs -> List.iter (printfn "%d") xs; xs)

OneПоследний вариант, который я могу придумать, это полностью разветвить конвейер:

let myList =
    numbers
    |> List.map square
    |> fun xs ->
          xs |> List.iter (printfn "%d")
          xs
          |> List.filter isOdd
          |> fun xs ->
                xs |> List.iter (printfn "%d")
                xs
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...