Skip to content

Instantly share code, notes, and snippets.

@gusbicalho
Created March 5, 2022 21:29
Show Gist options
  • Save gusbicalho/4eed4e4f571f3fa49040cfbcae0fa3ed to your computer and use it in GitHub Desktop.
Save gusbicalho/4eed4e4f571f3fa49040cfbcae0fa3ed to your computer and use it in GitHub Desktop.
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}
module StagedPower where
import Language.Haskell.TH (Q, TExp)
type Code a = Q (TExp a)
-- Monomorphic
qpower :: Int -> Q (TExp Int) -> Q (TExp Int)
qpower 0 _ = [||1||]
qpower i n = [||$$n * $$(qpower (i - 1) n)||]
-- Polymorphic
newtype Powerer = Pwr {getPwr :: forall a. Num a => a -> a}
makePowers :: forall a. Code a -> Code (a -> a -> a) -> Int -> Code (a -> a)
makePowers one times power = [||\n -> $$(go [||n||] power)||]
where
go :: Code a -> Int -> Code a
go _ 0 = one
go n i = [||$$times $$n $$(go n (i -1))||]
qpowerer :: Int -> Q (TExp Powerer)
qpowerer i =
[||
Pwr $ \a ->
let times = (*)
one = 1
in $$(makePowers [||one||] [||times||] i) a
||]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment