all!
What is wrong with this code? I cannot understand what I am doing wrong with Seq.Map. Here is the error message: The type 'unit' is not compatible with the type '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.开发者_StackOverflow社区map getPathToLibFile // error in this line
|> Seq.iter (printfn "Path to libs: %s")
Is there any understandable examples on Seq.Map?
PS Example from wiki (it works):
(* 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
I suspect the problem is actually your previous call.
Seq.iter
doesn't return anything (or rather, returns unit
) so you can't use it in the middle of a pipeline. Try this:
let importAllLibs (lines:string[]) =
lines
|> Seq.filter isImportLine
|> Seq.map getPathToLibFile
|> Seq.iter (printfn "Path to libs: %s")
... and then if you really need to print out the "libs found" line, you can add another mapping which performs the printing and just returns the input:
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")
This may well be invalid F#, but I think the aim is right :)
WebSharper includes an operator you can define yourself like this:
let (|!>) a f = f a; a
Allowing you to call a function of type 'a -> unit
on the input value returning the same value.
Fixing your code would require but a slight modification:
lines
|> Seq.filter isImportLine
|!> Seq.iter (printfn "Libs found: %s")
|> Seq.map getPathToLibFile // error in this line
|> Seq.iter (printfn "Path to libs: %s")
On the other hand you would end up iterating the collection twice which might not be what you want.
A better approach would be to define a function Do (lowercase do
being a reserved keyword in F#) which introduces a side effect on iterating the sequence. Rx.NET (Ix) provides such a function in EnumerableEx:
let Do f xs = Seq.map (fun v -> f v; v) xs
and then you can introduce the side effect like so:
lines
|> Seq.filter isImportLine
|> Do (printfn "Libs found: %s")
|> Seq.map getPathToLibFile // error in this line
|> Seq.iter (printfn "Path to libs: %s")
The side effect will be introduced only upon iterating the collection on the last line.
精彩评论