Skip to content

Instantly share code, notes, and snippets.

@dagit
Last active September 8, 2016 14:35
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dagit/6082516 to your computer and use it in GitHub Desktop.
Save dagit/6082516 to your computer and use it in GitHub Desktop.
-- http://www.cis.upenn.edu/~eir/papers/2014/axioms/axioms-extended.pdf
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE ScopedTypeVariables #-}
module ZipWith (zipWith) where
data Nat
= Zero
| Succ Nat
type family Listify (n :: Nat) arrows where
Listify Zero a = [a]
Listify (Succ n) (a -> b) = [a] -> Listify n b
data NumArgs :: Nat -> * -> * where
NAZero :: NumArgs Zero a
NASucc :: NumArgs n b -> NumArgs (Succ n) (a -> b)
listApply :: NumArgs n a -> [a] -> Listify n a
listApply NAZero fs = fs
listApply (NASucc na) fs =
\args -> listApply na (apply fs args)
where
apply :: [a -> b] -> [a] -> [b]
apply (f : fs) (x : xs) = f x : apply fs xs
apply _ _ = []
type family CountArgs (f :: *) :: Nat where
CountArgs (a -> b) = Succ (CountArgs b)
CountArgs result = Zero
class CNumArgs (numArgs :: Nat) (arrows :: *) where
getNA :: NumArgs numArgs arrows
instance CNumArgs Zero a where
getNA = NAZero
instance CNumArgs n b =>
CNumArgs (Succ n) (a -> b) where
getNA = NASucc getNA
zipWith :: forall f. CNumArgs (CountArgs f) f
=> f -> Listify (CountArgs f) f
zipWith fun = listApply (getNA :: NumArgs (CountArgs f) f) (repeat fun)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment