实现F#Workflow构建器:Yield,For,YieldFrom

时间:2010-12-05 10:35:37

标签: f#

我正在努力了解我对F#工作流程构建器的理解。因此,我想出了以下示例以进行实验。

type failSafeSeq() =
    member this.For(seq, mapFunction) = seq |> Seq.map mapFunction
    member this.Yield(yieldExpr) = yieldExpr
    member this.YieldFrom(yieldBang) = yieldBang
    member this.Combine(a, b) = Seq.append a b
    member this.Delay(delayFun) = delayFun()
    member this.Zero() = Seq.empty 

let failSafe = new failSafeSeq();


let rec allFilesSeq dir =
    failSafe { for file in Directory.EnumerateFiles(dir) do yield file
               for subdir in Directory.EnumerateDirectories dir do yield! (allFilesSeq subdir) }

使用上面的代码,编译在“(allFilesSeq subdir)”处失败,并显示错误消息:

This expression was expected to have type     string     but here has type     seq<string>

我已经尝试了许多不同的咒语来修复此错误,但没有成功。我错过了什么?

1 个答案:

答案 0 :(得分:2)

type failSafeSeq() =
    member this.For(seq, mapFunction) = Seq.collect mapFunction seq
    member this.Yield(yieldExpr) = Seq.singleton yieldExpr
    member this.YieldFrom(yieldBang) = yieldBang
    member this.Combine(a, b) = Seq.append a b
    member this.Delay(delayFun) = delayFun()
    member this.Zero() = Seq.empty 
  • 用于生成一系列序列,因此您需要将它们展平
  • Yield应该在计算类型中包装值 - 在您的情况下生成具有一个元素的序列