Skip to content

Instantly share code, notes, and snippets.

@pacak
Last active August 29, 2015 14:21
Show Gist options
  • Save pacak/378dec398895efdabb09 to your computer and use it in GitHub Desktop.
Save pacak/378dec398895efdabb09 to your computer and use it in GitHub Desktop.
refold to compute factorial
{-# LANGUAGE TemplateHaskell, TypeFamilies, DeriveFunctor #-}
{-# LANGUAGE BangPatterns #-}
import Data.Functor.Foldable
import TH
import Data.List
fact1 :: Integer -> Integer
fact1 n = product [1..n]
reduceProduct [] = []
reduceProduct [x] = [x]
reduceProduct (a:b:xs) = (a*b) : reduceProduct xs
product' [] = 1
product' [x] = x
product' xs = product' (reduceProduct xs)
fact2 :: Integer -> Integer
fact2 n = product' [1..n]
data BTree = Lf Integer | T BTree BTree deriving (Show)
makePrim ''BTree
fact3 :: Integer -> Integer
fact3 i = refold cpsi apsi (1, i)
where
cpsi :: Base BTree Integer -> Integer
cpsi (LfF i) = i
cpsi (TF l r) = l * r
apsi :: (Integer, Integer) -> Base BTree (Integer, Integer)
apsi (f, t) | f >= t = LfF f
| otherwise = let r = (t + f) `div` 2 in TF (f, r) (r+1, t)
main :: IO ()
main = do
print $ length $ show $ fact3 1000000
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment