类型类别,通用记忆

问题描述 投票:0回答:1

y 类型发生了一些非常奇怪的事情,我很不明白这是否合理。我倾向于认为不会。

这段代码运行良好:

   type DictionarySingleton private () = 
      static let mutable instance = Dictionary<string*obj, obj>()
      static member Instance = instance

   let  memoize  (f:'a -> 'b) = 
      fun (x:'a) ->
         let key = f.ToString(), (x :> obj)
         if (DictionarySingleton.Instance).ContainsKey(key) 
         then let r = (DictionarySingleton.Instance).[key]
              r :?> 'b
         else 
              let res = f x 
              (DictionarySingleton.Instance).[key] <- (res :> obj)
              res

这个人抱怨

   type DictionarySingleton private () = 
      static let mutable instance = Dictionary<string*obj, _>()
      static member Instance = instance

   let  memoize  (f:'a -> 'b) = 
      fun (x:'a) ->
         let key = f.ToString(), (x :> obj)
         if (DictionarySingleton.Instance).ContainsKey(key) 
         then let r = (DictionarySingleton.Instance).[key]
              r :?> 'b
         else 
              let res = f x 
              (DictionarySingleton.Instance).[key] <- (res :> obj)
              res

区别仅在于字典定义中的下划线。 推断的类型是相同的,但从 r 到类型 'b 的动态转换会出现错误。

“此运行时强制...某些类型等不允许运行时类型测试..”

我遗漏了什么还是边缘粗糙?

f# type-inference
1个回答
1
投票

如果分两步进行编译,首先是 Type

DictionarySingleton
,然后是 Function
memoize
,它就可以工作了。 看起来编译器首先尝试找出下划线的类型(可能是泛型类型),在确定它是
obj
之前,它还尝试推断 r 的类型。所以到那时它仍然没有与
obj
统一,这就是为什么你一次性编译会失败的原因。

© www.soinside.com 2019 - 2024. All rights reserved.