## More Pi

So, in my previous post I started converting a spigot algorithm for calculating pi from Haskell to Perl 6. I apologize for being away for so long, but I’m back at it now.

Interestingly, while I thought the previous `stream` function was much clearer in p6, this time out I think I have to give the edge to Haskell.

```convert :: (Integer,Integer) -> [Integer] -> [Integer]
convert (m,n) xs = stream next safe prod cons init xs
where
init = (0%1, 1%1)
next (u,v) = floor (u*v*n’)
safe (u,v) y = (y == floor ((u+1)*v*n’))
prod (u,v) y = (u - fromInteger y/(v*n’), v*n’)
cons (u,v) x = (fromInteger x + u*m’, v/m’)
(m’,n’) = (fromInteger m, fromInteger n)
```

The difference comes from Haskell’s extremely elegant on-the-fly pair notation. When I translate that to p6, I get

```sub convert(\$m, \$n, @x) {
stream(-> \$u { floor(\$u.key * \$u.value * \$n); },
-> \$u, \$y { \$y == floor((\$u.key + 1) * \$u.value * \$n); },
-> \$u, \$y { \$u.key - \$y / (\$u.value * \$n) => \$u.value * \$n; },
-> \$u, \$x { \$x + \$u.key * \$m => \$u.value / \$m; },
0/1 => 1/1,
@x);
}
```

Even with p6’s big advantage in not having to explicitly convert integers to rationals, the pair thing makes this round a win for Haskell, IMO.

Perhaps one of the other p6 programmers out there can think of a more elegant way of handling this…

Update: They sure can! The esteemed TimToady pointed out Perl 6 can do something almost identical to the Haskell approach, skipping Pairs altogether:

```sub convert(\$m, \$n, @x) {
stream(-> [\$u, \$v] { floor(\$u * \$v * \$n); },
-> [\$u, \$v], \$y { \$y == floor((\$u + 1) * \$v * \$n); },
-> [\$u, \$v], \$y { [\$u - \$y / (\$v * \$n), \$v * \$n]; },
-> [\$u, \$v], \$x { [\$x + \$u * \$m, \$v / \$m]; },
[0/1, 1/1],
@x);
}
```

This version compares very well with the Haskell version, IMO!