packages feed

TYB-0.2.0: examples/List.hs

{-# LANGUAGE TemplateHaskell #-}
{-# OPTIONS -Wall #-}
{-# OPTIONS -fno-warn-type-defaults #-} -- See Note [Type defaults] in Syntax.hs

module List where

import Data.Generics.TH
import Control.Monad.State

----------------------------------------
-- List
----------------------------------------

-- This is slower than "Prelude.sum" because that uses accumulator
-- style due to the foldl in it.
sum :: [Int] -> Int
sum = $(everything [|(+)|] (mkQ [|0|] 'f) [t|[Int]|]) where
  f :: Int -> Int
  f = id

-- As fast as sum
sum_acc :: [Int] -> Int
sum_acc xs = $(everythingAccR (mkQ [|id|] 'f) [t|[Int]|]) xs 0 where
  f :: Int -> (Int -> Int)
  f = (+)

-- Or by reifying the types from the function name (and using a strict accumulator):
sum_for :: [Int] -> Int
sum_for xs = $(everythingForL' 'f [t|[Int]|]) xs 0 where
  f :: Int -> Int -> Int
  f = (+)

map :: (Int -> Int) -> [Int] -> [Int]
map f = $(everywhere (mkT 'f) [t|[Int]|])

shift :: [Int] -> [Int]
shift xs = evalState ($(everywhereM (mkM 'go) [t|[Int]|]) xs) 0
 where
 go :: Int -> State Int Int
 go i = get >>= \v -> put i >> return v