-
-
Save wz1000/2dee93d3b07825d1ae43cf43012adcc0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# LANGUAGE UnboxedTuples #-} | |
{-# LANGUAGE RankNTypes #-} | |
{-# LANGUAGE BangPatterns #-} | |
{-# LANGUAGE KindSignatures #-} | |
{-# LANGUAGE PolyKinds #-} | |
{-# LANGUAGE DataKinds #-} | |
{-# LANGUAGE TypeOperators #-} | |
{-# LANGUAGE ScopedTypeVariables #-} | |
{-# LANGUAGE FlexibleContexts #-} | |
{-# LANGUAGE FlexibleInstances #-} | |
{-# LANGUAGE GADTs #-} | |
{-# LANGUAGE MagicHash #-} | |
{-# LANGUAGE TypeApplications #-} | |
{-# LANGUAGE TypeFamilies #-} | |
{-# LANGUAGE TypeFamilyDependencies #-} | |
module Main where | |
import Prelude hiding (foldl, (.), id, flip) | |
import qualified Prelude | |
import GHC.Exts | |
import Data.Kind | |
type Lev (a :: TYPE r) = Void# -> a | |
unlift :: Lev (a :: TYPE r) -> a | |
unlift k = k void# | |
class Call (r :: RuntimeRep) where | |
callF :: forall r' (a :: TYPE r) (b :: TYPE r'). (Lev a -> Lev b) -> a -> b | |
mapF :: forall r' (a :: TYPE r) (b :: TYPE r'). (a -> b) -> Lev a -> Lev b | |
instance Call LiftedRep where | |
callF f x = f (\_ -> x) void# | |
mapF f k _ = f (k void#) | |
instance Call IntRep where | |
callF f x = f (\_ -> x) void# | |
mapF f k _ = f (k void#) | |
id :: forall r (a :: TYPE r). Call r => a -> a | |
id = callF Prelude.id | |
(.) :: forall ra rb rc (b :: TYPE rb) (c :: TYPE rc) (a :: TYPE ra). (Call ra, Call rb) => (b -> c) -> (a -> b) -> (a -> c) | |
(.) f g = callF (mapF f Prelude.. mapF g) | |
fold :: forall r a (b :: TYPE r). Call r => (a -> b -> b) -> [a] -> b -> b | |
fold f [] = id | |
fold f (x:xs) = (fold f xs) . (f x) | |
flip :: forall ra rb rc (b :: TYPE rb) (c :: TYPE rc) (a :: TYPE ra). (Call ra, Call rb) => (a -> b -> c) -> b -> a -> c | |
flip f = callF (\lb _ -> callF (\la -> mapF (\k -> unlift $ mapF k lb) $ mapF f la)) | |
foldl :: forall r a (b :: TYPE r). Call r => (b -> a -> b) -> b -> [a] -> b | |
foldl f = flip (fold (flip f)) | |
usum :: [Int] -> Int | |
usum xs = I# (foldl (\acc (I# x) -> acc +# x) 0# xs) | |
{-# NOINLINE usum #-} | |
bsum :: [Int] -> Int | |
bsum xs = foldl (+) 0 xs | |
{-# NOINLINE bsum #-} | |
main = print $ usum [1..1000000] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment