在我追求更多F#的過程中,我試圖實現一個由Paul Graham here描述的「蓄能器發電機」。我最好的解決方案至今是完全動態類型:F中的蓄能器發電機#
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
類型標註的代碼無法編譯,因爲編譯器推斷X形int -> obj
- 雖然acc
已註釋返回obj->obj
。爲什麼是這樣,我可以避免它? - 任何想法來改善這種動態類型的版本?
- 是否有可能用適當的靜態類型來實現它?也許會員約束? (這可能在Haskell中,但不在OCaml,AFAIK中)
你說得對。我對Haskell不太瞭解。我在接受的解決方案頁面上看到了Haskell(http://www.paulgraham.com/accgen.html),並認爲它可行。 現在我嘗試了它,我發現Haskell解決方案似乎並不能滿足要求(它靜態地決定如果您在任何地方使用帶浮點的生成函數,則一直使用浮點數)。 – wmeyer 2010-09-05 01:17:01