作为使用策略模式的项目的一部分,我正在尝试编写一个函数,它创建一个函数,每次应用时都会返回无限序列的下一个值。目前我正在使用这个狡猾的 GetNext 功能:
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
location / {
resolver 127.0.0.1 ipv6=off;
proxy_pass http://$host;
}
}
}
我希望 FunctionFactory 看起来像这样:
let GetNext<'T> (enumerator:System.Collections.Generic.IEnumerator<'T>) =
let n = enumerator.MoveNext()
enumerator.Current
let FunctionFactory<'T> =
let s = 0.0 |> Seq.unfold (fun i -> Some(i, if 0.0 = i then 1.0 else 0.0))
let enumerator = s.GetEnumerator()
(fun (ignoredParam:'T) -> GetNext enumerator )
ignoredParam 用于其他通过相同策略模式并依赖于它提供的上下文的函数。由于这看起来很糟糕,我真的有两个问题。为什么没有 Seq.next ?实现各种序列表达式的正确/优雅方法是什么,这些表达式可以注入到这样的策略框架中?
按照Fyodor Soikin的回答编辑 - 此时序列表达对我很有吸引力,因为它们帮助我思考我正在看的问题。我想用更复杂的输入序列构建这种模式,而不是可变的命令式样式代码。
答案 0 :(得分:6)
您是否注意到您从未处置过调查员?
这就是没有Seq.next
的原因:它的使用需要不合理的设计。
关于第二个问题,并不完全清楚什么是&#34;这个&#34;你正试图实施的。就我可以从代码中收集而言,你正试图制作一个有状态的程序&#34;这将产生1.0或0.0,每次调用时都会切换。正确?
如果是这样,我会通过可变值来实现。开销比序列少很多:
let FunctionFactory<'T> =
let mutable flag = true
fun (_:'T) ->
flag <- not flag
if flag then 1.0 else 0.0