The zipWith implementation is a canonical example of a performant solution that makes good use of haskell's laziness and terseness. That said, there are a couple of fun variations that I think are nice to look at.
First: I think it's always fun to point out that there's a closed-form solution:
This is only accurate up to around the 25th Fibonacci number because of floating point errors, but it can be fun to use when conversations about how to calculate it come up.
Second: I think it's fun to point out that (->) has an Applicative instance that you can use:
fibs=0:1:(zipWith(+)<*>tail)fibs
or in a slightly less terse style
fibs=letnext=zipWith(+)<*>tailin0:1:nextfibs
I'm not sure either of these is a "best" or "favorite" solution, since that's going to be highly dependent on what your specific need is, but I think each of them provides some enlightening information.
The
zipWith
implementation is a canonical example of a performant solution that makes good use of haskell's laziness and terseness. That said, there are a couple of fun variations that I think are nice to look at.First: I think it's always fun to point out that there's a closed-form solution:
This is only accurate up to around the 25th Fibonacci number because of floating point errors, but it can be fun to use when conversations about how to calculate it come up.
Second: I think it's fun to point out that
(->)
has anApplicative
instance that you can use:or in a slightly less terse style
I'm not sure either of these is a "best" or "favorite" solution, since that's going to be highly dependent on what your specific need is, but I think each of them provides some enlightening information.
Thanks for sharing Rebecca, I've actually learnt something new today about how to use
<*>
.It's very neat, I like it!