虽然我的代码做了我需要的,但我觉得我缺少一些编码技术来以更简洁的方式实现这种东西。
目标是撰写项目并在此过程中为其提供Id值。 在这里,我认为可以通过多种方式简化和改进代码。如果我知道,怎么......
type Foo = | A of int | B of int | C of int
let ids startvalue = Seq.initInfinite (fun i -> i + startvalue)
let makeA ids =
A(Seq.head ids), Seq.skip 1 ids
let makeB ids =
B(Seq.head ids), Seq.skip 1 ids
let makeC ids =
C(Seq.head ids), Seq.skip 1 ids
let config = [makeA; makeA; makeC; makeB]
let create (ids : seq<int>) (cfg : (seq<int> -> Foo * seq<int>) list) : Foo list * seq<int> =
let rec cre ids1 acc cl =
match cl with
| [] -> (acc,ids1)
| x::xs ->
let v,ids2 = x ids1
cre ids2 (acc @ [v]) xs
cre ids [] cfg
let result : Foo list * seq<int> = create (ids 0) config
这导致非常简单:
val结果:Foo list * seq =([A 0; A 1; C 2; B 3],)
不知怎的,我觉得应该有一种更简单的方法来实现同样的目标。
事实上,我知道一种方法可以使它变得更简单,但这会涉及可变的状态和记忆(因此可能会被认为更糟):
let idgen startvalue =
let v = ref startvalue
fun () ->
let result = !v
v := !v + 1
result
通过这样接收的生成器函数,我可以摆脱所有这些元组,至少我也可以摆脱create
函数并简单地写:
let ids = idgen 0
let result =
[
A(ids())
A(ids())
C(ids())
B(ids())
]
但是也应该存在一种“功能性”的方式来更简单地完成它。
答案 0 :(得分:4)
看起来你想要的是获取两个序列,一个是函数,另一个是参数,并通过将函数应用于相应的参数来产生新的序列,其中在你的特定情况下,参数是连续的整数,函数是联合情况构造函数。这是一个正确的评估吗?
如果是这样,我会做什么:
let create args funs =
Seq.zip args funs
|> Seq.map (fun (arg, fn) -> fn arg)
|> List.ofSeq
let result = create (ids 0) [A; A; C; B]
答案 1 :(得分:0)
type Foo = | A of int | B of int | C of int
let ids startvalue = Seq.initInfinite (fun i -> i + startvalue)
let config = [A; A; C; B]
let create ids i cfg =
let ids' = ids i
let nextI = i + List.length cfg
(Seq.map2 id cfg ids'), nextI
let result, nextI = create ids 0 config
let result2, nextI2 = create ids nextI config
这里有几个注意事项:
A
,B
和C
是int -> Foo
类型的构造函数。您可以直接将它们用作函数并消除重复的包装函数; Seq.map2
能够处理不同长度的序列,并忽略较长的序列; id
是fun f number -> f number
的快捷方式,如果您发现id
不清楚,请使用较长的ids
功能重构为Seq.initInfinite id |> Seq.skip startvalue
。List
。 已更新以接收保留i
和nextI
。
答案 2 :(得分:0)
正如Fyodor在他的回答中指出的那样,你真的只想将构造函数应用于连续的整数。您可以使用内置的mapi,将整个程序编写为:
type Foo = | A of int | B of int | C of int
let config = [A; A; B; C]
let create offset = List.mapi (fun i f -> f (offset + i))
create 78 config
// val it : Foo list = [A 78; A 79; B 80; C 81]