Seq.Map строка-> строка - PullRequest
       21

Seq.Map строка-> строка

0 голосов
/ 15 августа 2011

все!

Что не так с этим кодом?Я не могу понять, что я делаю не так с Seq.Map.Вот сообщение об ошибке: Тип 'unit' не совместим с типом 'seq <' a> '

let getPathToLibFile value =
    let regex = new Regex("\"(?<data>[^<]*)\"")
    let matches = regex.Match(value)
    matches.Value

let importAllLibs (lines:string[]) =
    lines
    |> Seq.filter isImportLine
    |> Seq.iter (printfn "Libs found: %s")
    |> Seq.map getPathToLibFile // error in this line
    |> Seq.iter (printfn "Path to libs: %s")

. Есть ли понятные примеры на Seq.Map?

PSПример из вики (работает):

(* Fibonacci Number formula *)
let rec fib n =
    match n with
    | 0 | 1 -> n
    | _ -> fib (n - 1) + fib (n - 2)

(* Print even fibs *)
[1 .. 10]
|> List.map     fib
|> List.filter  (fun n -> (n % 2) = 0)
|> printlist

Ответы [ 2 ]

4 голосов
/ 15 августа 2011

Я подозреваю, что проблема на самом деле ваш предыдущий вызов.

Seq.iter ничего не возвращает (или, скорее, возвращает unit), поэтому выне может использовать его в середине конвейера.Попробуйте это:

let importAllLibs (lines:string[]) =
    lines
    |> Seq.filter isImportLine
    |> Seq.map getPathToLibFile
    |> Seq.iter (printfn "Path to libs: %s")

... и затем, если вам действительно нужно распечатать строку "libs found", вы можете добавить другое отображение, которое выполняет печать и просто возвращает ввод:

let reportLib value =
    printfn "Libs found: %s" value
    value

let importAllLibs (lines:string[]) =
    lines
    |> Seq.filter isImportLine
    |> Seq.map reportLib
    |> Seq.map getPathToLibFile
    |> Seq.iter (printfn "Path to libs: %s")

Это вполне может быть недействительным F #, но я думаю, что цель правильна:)

0 голосов
/ 18 августа 2011

В WebSharper есть оператор, которого вы можете определить следующим образом:

let (|!>) a f = f a; a

Позволяет вам вызвать функцию типа 'a -> unit для входного значения, возвращающего то же значение.

Исправление вашего кода потребует небольшого изменения:

lines
|> Seq.filter isImportLine
|!> Seq.iter (printfn "Libs found: %s")
|> Seq.map getPathToLibFile // error in this line
|> Seq.iter (printfn "Path to libs: %s")

С другой стороны, вы должны будете повторить коллекцию дважды, что может оказаться не тем, что вы хотите.

Лучшим подходом было бы определение функции Do (строчная буква do является зарезервированным ключевым словом в F #), которая вводит побочный эффект при итерации последовательности. Rx.NET (Ix) предоставляет такую ​​функцию в EnumerableEx:

let Do f xs = Seq.map (fun v -> f v; v) xs

и тогда вы можете ввести побочный эффект следующим образом:

lines
|> Seq.filter isImportLine
|> Do (printfn "Libs found: %s")
|> Seq.map getPathToLibFile // error in this line
|> Seq.iter (printfn "Path to libs: %s")

Побочный эффект будет введен только после итерации коллекции в последней строке.

...