Last active
January 30, 2020 14:45
-
-
Save JakobBruenker/6a87367b1eded2f0a18b73e2333b10c2 to your computer and use it in GitHub Desktop.
https://gist.github.com/merijn/dc00bc7cebd6df012c5e without type families
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 DataKinds #-} | |
{-# LANGUAGE FlexibleContexts #-} | |
{-# LANGUAGE FlexibleInstances #-} | |
{-# LANGUAGE GADTs #-} | |
{-# LANGUAGE KindSignatures #-} | |
{-# LANGUAGE FunctionalDependencies #-} | |
{-# LANGUAGE TypeOperators #-} | |
{-# LANGUAGE UndecidableInstances #-} | |
{-# LANGUAGE ConstraintKinds #-} | |
{-# LANGUAGE EmptyCase #-} | |
{-# LANGUAGE LambdaCase #-} | |
module HList where | |
import Prelude hiding (head, tail, zip) | |
import GHC.Exts (Constraint) | |
data HList :: [*] -> * where | |
Nil :: HList '[] | |
Cons :: a -> HList l -> HList (a ': l) | |
instance Show (HList '[]) where | |
show Nil = "Nil" | |
instance (Show a, Show (HList l)) => Show (HList (a ': l)) where | |
show (Cons x xs) = "Cons " ++ show x ++ " (" ++ show xs ++ ")" | |
head :: HList (a ': l) -> a | |
head (Cons h _) = h | |
tail :: HList (a ': l) -> HList l | |
tail (Cons _ t) = t | |
class Fun (l :: [*]) (r :: *) t | l r -> t where | |
apply :: t -> HList l -> r | |
instance Fun '[] r r where | |
apply x Nil = x | |
instance Fun as r t => Fun (a ': as) r (a -> t) where | |
apply f (Cons h t) = apply (f h) t | |
class Zip (l :: [*]) (k :: [*]) (t :: [*]) | l k -> t where | |
zip :: HList l -> HList k -> HList t | |
instance Zip '[] '[] '[] where | |
zip Nil Nil = Nil | |
instance Zip as bs t => Zip (a ': as) (b ': bs) ((a, b) ': t) where | |
zip (Cons a as) (Cons b bs) = Cons (a, b) (zip as bs) | |
instance ("Error!" ~ "List length are unequal!", Zip as '[] t) => Zip (a ': as) '[] t where | |
zip = \case | |
instance ("Error!" ~ "List length are unequal!", Zip '[] bs t) => Zip '[] (b ': bs) t where | |
zip = \case | |
someList :: HList [Bool, Char, Int] | |
someList = Cons True (Cons 'c' (Cons 1 Nil)) | |
anotherList :: HList [Maybe (), [a], Double] | |
anotherList = Cons (Just ()) (Cons [] (Cons 2.0 Nil)) | |
zippedList :: HList [(Bool, Maybe ()), (Char, [a]), (Int, Double)] | |
zippedList = zip someList anotherList | |
main :: IO () | |
main = print $ apply (,,) someList |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment