Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在F#(类型约束)中实现泛型.Dictionary的扩展方法_F# - Fatal编程技术网

如何在F#(类型约束)中实现泛型.Dictionary的扩展方法

如何在F#(类型约束)中实现泛型.Dictionary的扩展方法,f#,F#,可能重复: 我想在System.Collections.Generic.Dictionary中添加F#中的扩展方法。问题是我似乎无法正确地获得类型约束。我希望下面的方法能奏效: type Dictionary<'k, 'd when 'k : equality> with static member ofList (xs:list<'k * 'd>) : Dictionary<'k, 'd> = let res = new Dictio

可能重复:

我想在System.Collections.Generic.Dictionary中添加F#中的扩展方法。问题是我似乎无法正确地获得类型约束。我希望下面的方法能奏效:

type Dictionary<'k, 'd when 'k : equality> with

   static member ofList (xs:list<'k * 'd>) : Dictionary<'k, 'd> =
       let res = new Dictionary<'k, 'd> ()
       for (k, d) in xs do
           res.Add (k, d)
       res

type Dictionary出于某种原因,类型参数的名称必须匹配-这对我来说很好

open System.Collections.Generic
type Dictionary<'TKey, 'TValue>  with
   static member ofList (xs:list<'k * 'd>) : Dictionary<'k, 'd> =
       let res = new Dictionary<'k, 'd> ()
       for (k, d) in xs do
           res.Add (k, d)
       res

很好用。这实际上现在是有道理的。当参数相同时,由于
新字典
,存在一个额外的未指定约束-
'k:equality
。但是,由于某些原因,我们无法在扩展定义中设置约束(避免重复?),因此出现了一个错误。

您将无法摆脱警告,因为您引用的是一个不存在的类型,
Dictionary
,而不是
Dictionary
。如果您希望以这种方式访问字典模块,则可以创建一个字典模块

open System.Collections.Generic

type Dictionary<'a,'b>  with
  static member ofList (xs:list<'k*'v>) =
      let res = new Dictionary<_,_> ()
      for k, v in xs do
          res.Add (k, v)
      res    

module Dictionary = 
   let ofList xs = Dictionary<_,_>.ofList xs
open System.Collections.Generic
使用
列表的静态成员(xs:list)=
let res=新字典()
对于k,v在xs-do中
决议添加(k,v)
物件
模块字典=
let of list xs=Dictionary.of list xs
然后你就摆脱了警告

Dictionary.ofList ["1",1;"2",2];;
val it : Dictionary<string,int> = dict [("1", 1); ("2", 2)]
Dictionary.of列表[“1”,1;“2”,2];;
valit:Dictionary=dict[(“1”,1);(“2”,2)]

< /代码> 如果需要各种集合的<代码> OfSeq 函数,您可以考虑类似于C.*集合初始化器的方法。也就是说,使用
Add
方法使其适用于任何集合。这也回避了你目前的问题

open System.Collections.Generic
开放系统.Collections.Concurrent
模块字典=
设方程s=
设t=new^t()
对于k,v在s中
(^T:(成员添加:^K*^V->^R)(T,K,V))|>忽略
T
模块集合=
设方程s=
设t=new^t()
为v在s中做什么
(^T:(成员添加:^V->^R)(T,V))|>忽略
T
开放词典
让xs=List.init 9(乐趣i->stringi,i)
设d1:Dictionary=ofSeq xs
设d2:SortedDictionary=ofSeq xs
设d3:SortedList=ofSeq xs
公开收藏
让ys=List.init 9 id
设c1:ResizeArray=ofSeq ys
设c2:HashSet=ofSeq ys
设c3:ConcurrentBag=ofSeq ys
有趣的是,您甚至可以将其限制为具有特定构造函数重载的集合类型。例如,如果要使用结构相等,可以执行以下操作:

let t=(^t:(新:IEqualityComparer<^K>->^t)(HashIdentity.Structural))

当调用其他参数时,是否能够重现警告?我使用的是警告级别为3的F#3.0。重命名之前的类型参数后,我得到了相同的行为(即没有约束的警告,以及问题中所示的约束的硬错误)。您看到了什么?第二个解决方案成功地关闭了警告(无论出于何种原因,因为仍然非常需要约束)。但是现在,当我尝试使用新方法时,出现了一个新的警告:“让f()=Dictionary.ofList[1,2]”现在会抱怨它无法理解“a”和“b”是什么,并建议我使用类似Dictionary.ofList的东西。关于如何解决这个问题有什么想法吗?@user1878761-用
Dictionary.ofList[1,1]调用它而不是
Dictionary.ofList[1,1]为我消除了错误。JP:非常感谢您的回答。我会在第二天左右接受它,除非其他人想出一种解决问题的方法,在实例化字典时,不需要显式类型参数。再次感谢。请参阅对发生的事情的完整解释。我不确定我是否理解。我一直在写List.map,而不是List.map。您的参数是否适用于列表?列表是FSharp.core中的一个模块。列表是System.Collections.Generic.List,两个完全不同的东西。第一个是不可变的单链表,第二个是C#中最常用的可变列表。F#list模块没有泛型类型参数,只包含操作F#list的函数。我现在真的不明白。我显然是指不可变的FSharp版本,因为Generic.List没有map方法。作为一个快速测试,您是否希望打开MSVC,并查看intellisense在声明“静态成员为f=123的类型列表”时的建议“在另一个答案中键入ListCheck kvb的链接。我们正在编一本新字典,这一事实就是引起这一警告的原因。我认为在上面这样的模块中加入“ofList”是一个不错的解决办法,我认为这不是重复。引用的帖子使用普通成员,而此问题使用静态成员。这对于理解编译器为什么坚持等式约束非常有用,但对于在不必明确指定类型参数的情况下消除警告则不太有用。(然而,这是迄今为止最有用的评论,非常感谢)在这两种情况下,问题是如何将扩展成员添加到
字典
类型,而另一个问题中的答案解释了为什么需要调用构造函数重载,该重载使用
iequalitycomparer
来避免类型约束。在您的情况下,您不能只使用
this.Comparer
,因为您正在创建一个静态成员,但您可以使用
EqualityComparer.Default
。这是我的观点。这些问题有不同的答案,对于不熟悉平等比较的人来说并不明显。不管是哪种方式,如果你愿意提交的话,我很乐意接受这个答案。非常感谢!哇!我不会想到的。非常感谢你。
type Dictionary<'a, 'b>  with
   static member ofList (xs:list<'k * 'd>) : Dictionary<'k, 'd> =
       let res = new Dictionary<'k, 'd> ()
       for (k, d) in xs do
           res.Add (k, d)
       res
open System.Collections.Generic

type Dictionary<'a,'b>  with
  static member ofList (xs:list<'k*'v>) =
      let res = new Dictionary<_,_> ()
      for k, v in xs do
          res.Add (k, v)
      res    

module Dictionary = 
   let ofList xs = Dictionary<_,_>.ofList xs
Dictionary.ofList ["1",1;"2",2];;
val it : Dictionary<string,int> = dict [("1", 1); ("2", 2)]