场景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中受限制”,因为运行时要求特定对象具有特定类型 – 即使您只以特定方式使用这些值,编译器和运行时也不会进行全局分析这需要看到.