这个模式是否有名称"输入折叠序列=空| ' a *的值(单位 - >'折叠序列)"

时间:2017-06-11 10:04:57

标签: f#

我一直在使用一些f#解析器和一些流媒体软件,我发现自己越来越多地使用这种模式。我发现它是序列的自然替代品,它具有一些天然优势。 以下是使用类型的一些示例函数。

type foldedSequence<'a> = 
    | Empty
    | Value of ' a * (unit -> 'a foldedSequence)

let rec createFoldedSequence fn state = 
    match fn state with
    | None -> Empty
    | Some(value, nextState) ->
        Value(value, (fun () -> unfold fn nextState))

let rec filter predicate = 
    function 
    | Empty -> Empty
    | Value(value, nextValue) -> 
        let next() = filter predicate(nextValue())
        if predicate value then Value(value, next)
        else next()

let toSeq<'t> = 
    Seq.unfold<'t foldedSequence, 't>(function 
        | Empty -> None
        | Value(value, nextValue) -> Some(value, nextValue()))

我想知道它是否有名称非常有用,所以我可以研究一些提示和技巧

3 个答案:

答案 0 :(得分:3)

要添加现有答案,我认为Haskellers可能会调用此a list monad transformer的通用版本。这个想法是你的类型定义看起来几乎像普通的F#list,除了它有一些额外的方面。你可以想象这样写:

type ListTransformer<'T> = 
   | Empty
   | Value of 'T * M<ListTransformer<'T>>

通过提供特定的M,您可以定义许多内容:

  • M<'T> = 'T为您提供普通的F#列表类型
  • M<'T> = unit -> 'T为您提供可以懒惰评估的序列
  • M<'T> = Lazy<'T>为您提供了LazyList(缓存已经评估过的元素)
  • M<'T> = Async<'T>为您提供asynchronous sequences

值得注意的是,在此定义中,LazyTransformer<'T>本身并不是延迟/延迟/异步值。这可能在某些情况下引起问题 - 例如当你需要执行一些异步操作来决定流是否为空时 - 所以更好的定义是:

type ListTransformer<'T> = M<ListTransformerInner<'T>>
and ListTransformerInner<'T> =
   | Empty
   | Value of 'T * ListTransformer<'T>

答案 1 :(得分:1)

这听起来像import dota2api import json import requests api = dota2api.Initialise("[Value API][2]") reponse = api.get_match_history_by_seq_num(start_at_match_seq_num=2829690055, matches_requested=1) response = str(hist) f = open('myfile.txt', 'w') f.write(response) f.close() 曾经在&#34; powerpack&#34;而且我觉得现在住在这里:

http://fsprojects.github.io/FSharpx.Collections/reference/fsharpx-collections-lazylist-1.html

https://github.com/fsprojects/FSharpx.Collections/blob/master/src/FSharpx.Collections/LazyList.fs

答案 2 :(得分:1)

您的类型接近于如何定义迭代,并且由于您已经提到了流式传输,因此这可能是您正在寻找的概念。

Iteratee IO是Oleg Kiselyov概述的懒惰IO方法。除了Haskell之外,还存在主要功能语言的实现,包括F#(作为FSharpx.Extras的一部分)。

这就是FSharpx定义Iteratee

的方式
type Iteratee<'Chunk,'T> =
    | Done of 'T * Stream<'Chunk>
    | Error of exn
    | Continue of (Stream<'Chunk> -> Iteratee<'Chunk,'T>)

另请参阅此博文:Iteratee in F# - part 1。请注意,似乎并不是第2部分。