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
Generics 编译器重写F中的类型定义(泛型)#_Generics_F#_Type Inference - Fatal编程技术网

Generics 编译器重写F中的类型定义(泛型)#

Generics 编译器重写F中的类型定义(泛型)#,generics,f#,type-inference,Generics,F#,Type Inference,情景1 let map = Dictionary<string,obj>() map.Add("1",10) map.Add("2",10L) map.Add("3","10") 在这里,编译器接受第一个条目,但它会将“a”约束为int,这会导致下两个条目失败,因为它们不是int 第一个问题:为什么它在场景1中编译,而在场景2中没有编译 第二个问题:在场景3中是否有防止“a”受到约束的方法,或者是否有某种模式可用于在F#中的集合中具有不同的类型(具体如本例中的函数类型) 值(obj

情景1

let map = Dictionary<string,obj>()
map.Add("1",10)
map.Add("2",10L)
map.Add("3","10")
在这里,编译器接受第一个条目,但它会将“a”约束为int,这会导致下两个条目失败,因为它们不是int

第一个问题:为什么它在场景1中编译,而在场景2中没有编译

第二个问题:在场景3中是否有防止“a”受到约束的方法,或者是否有某种模式可用于在F#中的集合中具有不同的类型(具体如本例中的函数类型)


值(obj/'a)的唯一用途是作为
println“%a”
的参数,我不明白为什么不能

在场景1中,编译器自动将参数向上转换为
map。将
int
等添加到
obj
,因为它可以看到
map.Add
需要
obj

在场景2中,它不能这样做,因为没有从
unit->int
unit->obj
的向上转换-您无法通过在函数周围手动插入
upcast
来进行转换

理论上,编译器可以改为更改函数体,但在调用
map.Add
时,强制转换的自动插入纯粹是局部的


在场景3中,您无法阻止
'a
受到约束,因为运行时要求特定对象具有特定类型-即使您仅以特定方式使用这些值,编译器和运行时也不会进行必要的全局分析。

对于场景2,您可以使用
修复向上转换到
obj
。例如,不要写
10
而是写
框10
。这也与以下最近的问题有关:谢谢你的快速回答!基于Jack P.答案,我认为处理这个问题的最佳方法是使用obj和box来处理每个条目?@Arkuray您不需要使用
obj
box
——只需
box
。您可以使用一个通用函数来允许客户端代码提交任何
单元->'a
,然后将其包装到一个新函数中,该函数执行以下装箱操作:
让map=Dictionaryobj>()
让addkey(f:unit->'a)=map.add(key,fun()->)框
let map = Dictionary<string,(unit -> obj)>()
map.Add("1",fun() -> 10)
map.Add("2",fun() -> 10L)
map.Add("3",fun() -> "10")
let map = Dictionary<string,(unit -> 'a)>()
map.Add("1",fun() -> 10)
map.Add("2",fun() -> 10L)
map.Add("3",fun() -> "10")