编译器覆盖F#中的类型定义(泛型)

场景1

let map = Dictionary<string,obj>()
map.Add("1",10)
map.Add("2",10L)
map.Add("3","10")

这符合罚款

情景2

let map = Dictionary<string,(unit -> obj)>()
map.Add("1",fun() -> 10)
map.Add("2",fun() -> 10L)
map.Add("3",fun() -> "10")

编译器在这里说它除了obj但在遇到10时找到了int

场景3

let map = Dictionary<string,(unit -> 'a)>()
map.Add("1",fun() -> 10)
map.Add("2",fun() -> 10L)
map.Add("3",fun() -> "10")

这里编译器接受第一个条目,但它会导致’a被约束为int,导致接下来的两个条目失败,因为它们不是int

第一个问题:为什么它在方案1中编译时不在方案2中?

第二个问题:无论如何都要阻止’a在场景3中被约束,或者是否存在可以使用的某种模式,这种模式可以在F#中的集合中实现不同类型(特定于此示例中的函数类型)?

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

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

在方案2中,它无法做到这一点,因为单元中没有可用的向上 – > int to unit – > obj – 您无法通过在函数周围手动插入向上转换来进行转换.

从理论上讲,编译器可以改变函数的主体,但是在调用map.Add时,自动插入强制转换是纯粹本地的.

您不能阻止“在场景3中受限制”,因为运行时要求特定对象具有特定类型 – 即使您只以特定方式使用这些值,编译器和运行时也不会进行全局分析这需要看到.

点赞