package main

import "fmt"

func main() {
    for _, n := range []int{0, 1, 2, 3, 4, 5, 10, 40, -1} {
        f, ok := arFib(n)
        if ok {
            fmt.Printf("fib%d =%d\n", n, f)
        } else {
            fmt.Println("fib undefined for negative numbers")
        }
    }
}

func arFib(n int) (int, bool) {
    switch {
    case n < 0:
        return 0, false
    case n < 2:
        return n, true
    }
    return yc(func(recurse fn) fn {
        return func(left, term1, term2 int) int {
            if left == 0 {
                return term1+term2
            }
            return recurse(left-1, term1+term2, term1)
        }
    })(n-2, 1, 0), true
}

type fn func(int, int, int) int
type ff func(fn) fn
type fx func(fx) fn

func yc(f ff) fn {
    return func(x fx) fn {
        return x(x)
    }(func(x fx) fn {
        return f(func(a1, a2, a3 int) int {
            return x(x)(a1, a2, a3)
        })
    })
}