В своем стремлении узнать больше о F # я попытался реализовать «генератор аккумуляторов», как описано здесь Полом Грэмом.
Эта проблема требует существования неопределенной числовой башни.У Лисп есть один, и он подходит для примеров Пола Грэма, потому что эта проблема была специально разработана для того, чтобы Лисп выглядел искусственно хорошо.
Вы можете реализовать числовую башню в F #, используя тип объединения (например, type number = Int of int | Float of float
) или боксом всё.Следующее решение использует последний подход:
let add (x: obj) (y: obj) =
match x, y with
| (:? int as m), (:? int as n) -> box(m+n)
| (:? int as n), (:? float as x)
| (:? float as x), (:? int as n) -> box(x + float n)
| (:? float as x), (:? float as y) -> box(x + y)
| _ -> failwith "Run-time type error"
let acc x =
let x = ref x
fun (y: obj) ->
x := add !x y
!x
let x : obj -> _ = acc(box 1)
do x(box 5)
do acc(box 3)
do printfn "%A" (x(box 2.3))
Однако в реальном мире числовые башни практически бесполезны.Если вы не будете очень осторожны, попытка извлечь уроки из подобных проблем принесет вам больше вреда, чем пользы.Вы должны спросить себя, почему мы не хотим числовую башню, не хотим боксировать и не хотим продвижение типа во время выполнения?
Почему мы просто не написали:
let x = 1
let x = x + 5
ignore(3)
let x = float x + 2.3
Мы знаем тип x
на каждом шагу.Каждый номер хранится без упаковки.Мы знаем, что этот код никогда не выдаст ошибку типа во время выполнения ...