0

全部!

这段代码有什么问题?我无法理解我对 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 上有什么可以理解的例子吗?

PS来自wiki的示例(有效):

(* 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
4

2 回答 2

5

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

Seq.iter不返回任何东西(或者更确切地说,返回unit),所以你不能在管道中间使用它。试试这个:

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

...然后,如果您确实需要打印出“找到的库”行,则可以添加另一个执行打印并仅返回输入的映射:

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

于 2011-08-15T13:35:25.650 回答
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")

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

于 2011-08-17T23:45:10.533 回答