为了了解更多 F#,我尝试实现 Paul Graham在此处描述的“累加器生成器” 。到目前为止,我最好的解决方案是完全动态类型:
open System
let acc (init:obj) : obj->obj=
let state = ref init
fun (x:obj) ->
if (!state).GetType() = typeof<Int32>
&& x.GetType() = typeof<Int32> then
state := (Convert.ToInt32(!state) + Convert.ToInt32(x)) :> obj
else
state := (Convert.ToDouble(!state) + Convert.ToDouble(x)) :> obj
!state
do
let x : obj -> obj = acc 1 // the type annotation is necessary here
(x 5) |> ignore
printfn "%A" (x 2) // prints "8"
printfn "%A" (x 2.3) // prints "10.3"
我有三个问题:
- 如果我删除 的类型注释
x
,代码将无法编译,因为编译器推断int -> obj
x 的类型 - 尽管acc
被注释为返回一个obj->obj
. 为什么会这样,我可以避免吗? - 有什么想法可以改进这个动态类型的版本吗?
- 是否可以使用适当的静态类型来实现这一点?也许有成员限制?(在 Haskell 中可以,但在 OCaml、AFAIK 中不行)