Реализация F # построителей рабочих процессов: Yield, For, YieldFrom - PullRequest
2 голосов
/ 05 декабря 2010

Я пытаюсь понять, как работают строители 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 Ответ

2 голосов
/ 05 декабря 2010
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 
  • For производит последовательность последовательностей, поэтому вам нужно сгладить их
  • Выход должен переносить значение в типе вычисления - в вашем случае создайте последовательность с одним элементом
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...