F#集合初始化器语法

时间:2011-03-17 15:13:15

标签: f# inline

F#中的collection initializer语法是什么?在C#中,您可以编写如下内容:

new Dictionary<string, int>() {
    {"One", 1},
    {"two", 2}}

我如何在F#中做同样的事情?我想我可以推出自己的语法,但似乎应该有一个内置的或标准的。

6 个答案:

答案 0 :(得分:69)

在F#中详细说明集合初始化,这里有几个例子:

只读字典

dict [ (1, "a"); (2, "b"); (3, "c") ]

seq(IEnumerable&lt; T&gt;)

seq { 0 .. 99 }

<强>列表

[1; 2; 3; 4; 5]

设置

set [1; 2; 3; 4; 5]

<强>阵列

[| 1; 2; 3; 4; 5 |]

答案 1 :(得分:26)

正如Jared所说,对于任意集合,没有内置的支持。但是,C#代码只是Add方法调用的语法糖,因此您可以将其转换为:

let coll = MyCollectionType()
["One", 1; "Two", 2] |> Seq.iter coll.Add

如果您想获得幻想,可以创建inline定义以进一步简化:

let inline initCollection s =
  let coll = new ^t()
  Seq.iter (fun (k,v) -> (^t : (member Add : 'a * 'b -> unit) coll, k, v)) s
  coll

let d:System.Collections.Generic.Dictionary<_,_> = initCollection ["One",1; "Two",2]

答案 2 :(得分:11)

我不相信F#有一个明确的集合初始化语法。但是,初始化F#集合通常非常容易。例如

let map = [ ("One", 1); ("Two", 2) ] |> Map.ofSeq

进入BCL系列通常会有点困难,因为他们并不总是拥有方便的转换功能。 Dictionary<TKey, TValue>可以工作,因为你可以使用LINQ方法

let map = 
  let list = [ ("One", 1); ("Two", 2) ] 
  System.Linq.Enumerable.ToDictionary(list, fst, snd)

答案 3 :(得分:3)

你可以使用相同的:

open System.Collections.Generic

Dictionary<int, string>(dict [ (1, "a"); (2, "b"); (3, "c") ])

干杯。

答案 4 :(得分:2)

缺少集合初始化程序对于一些以XAML为中心的API(如Workflow 4.0,它依赖于集合初始化程序而不是ctors)来说很烦人,例如

new Sequence { Activities = { WriteLine { Text = "In the sequence!" } } };

在这种情况下,命令式.Add()很尴尬,因为值是概念声明的,即使它在技术上是可变的/命令式的。但是,没有公共基类用于声明活动子项的所有活动的集合:“活动”成员是模式而不是接口,因此您不能只编写正常的帮助函数这会将孩子添加到任何活动中。幸运的是,F#成员限制得救了。

为了写这个:

Sequence() |> add [Sequence(DisplayName="InnerSeq"); WriteLine(Text = InArgument<_>("In the sequence!"))]

首先需要定义一个名为“add”的内联辅助函数:

let inline add (children: Activity seq) =
    let inline doAdd (activity: ^Activity) : ^Activity when ^Activity : (member get_Activities : unit -> Activity Collection) =
        let collection = (^Activity : (member get_Activities : unit -> Activity Collection) (activity))
        for child in children do
            collection.Add(child)
        activity
    doAdd

这仍然不如C#语法好,但至少它仍然是声明性的。恕我直言,这不是F#的错误,而是以集合初始化程序为中心的API,但至少F#允许解决方法。

答案 5 :(得分:0)

鉴于C#集合初始化器语法是用于调用.Add的语法糖并且暗示了一个可变集合 - 我不确定你会在F#中看到任何这样的语法。根据JaredPar的回答,它可以一次性初始化,也可以手动完成。