Seq.Map string-> string

时间:2011-08-15 13:32:16

标签: f# map seq

所有!

这段代码有什么问题?我无法理解Seq.Map的错误。 以下是错误消息:“单位”类型与“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上有没有可以理解的例子?

来自wiki的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 个答案:

答案 0 :(得分:4)

我怀疑问题是实际您之前的电话。

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#,但我认为目标是对的:)

答案 1 :(得分:0)

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")

只有在最后一行迭代集合时才会引入副作用。