Это не косяк. Так как F# должен обеспечивать взаимодействие с кодом на других .NET языках, которые кишат побочными эффектами, то использование ленивых вычислений по умолчанию весьма затруднено.
Есть явная ленивость:
let lazyValue = lazy (2 * 2)
let value = Lazy.force lazyValue
В strict языках Y-комбинатор формулируется по-другому — он принимает как аргумент не функцию a → a, а функцию (a → b) → (a → b):
let rec y f = f (fun x -> (y f) x)
let fib = y (fun f -> function
| 0 -> 0
| 1 -> 1
| n -> f (n — 1) + f (n — 2))
printfn "%i" (fib x)
F# не ленится :(