Skip to content

Instantly share code, notes, and snippets.

@JakobBruenker
Last active October 4, 2019 00:06
Show Gist options
  • Save JakobBruenker/42b35d27c025b6d286b0090461158fc4 to your computer and use it in GitHub Desktop.
Save JakobBruenker/42b35d27c025b6d286b0090461158fc4 to your computer and use it in GitHub Desktop.
variadic listof
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE FlexibleInstances #-}
module ListOf where
-- was a closed type family at first, but jle` said it might be cleaner to put
-- it inside the class, and I agree
class ListOfable t where
type Elem t
listOfWithAcc :: (e ~ Elem t) => [e] -> t
instance ListOfable [a] where
type Elem [a] = a
listOfWithAcc acc = reverse acc
instance (ListOfable t, Elem t ~ a) => ListOfable (a -> t) where
type Elem (a -> t) = a
listOfWithAcc acc x = listOfWithAcc (x:acc)
listOf :: ListOfable t => t
listOf = listOfWithAcc []
-------------------------------------------------------------------------------
-- with help from jle`
class ListOfable' a t | t -> a where
listOfWithAcc' :: [a] -> t
instance ListOfable' a [a] where
listOfWithAcc' acc = reverse acc
instance ListOfable' a t => ListOfable' a (a -> t) where
listOfWithAcc' acc x = listOfWithAcc' (x:acc)
listOf' :: ListOfable' a t => t
listOf' = listOfWithAcc' []
-------------------------------------------------------------------------------
main :: IO ()
main = do printList $ listOf 1 2 3
printList (listOf :: [Bool])
printList $ listOf "Hello" "World"
printList $ listOf False True False True
printList $ listOf (Just 4) (Just 3) Nothing Nothing (Just 2)
putStrLn "--------------"
printList $ listOf' 1 2 3
printList (listOf' :: [Bool])
printList $ listOf' "Hello" "World"
printList $ listOf' False True False True
printList $ listOf' (Just 4) (Just 3) Nothing Nothing (Just 2)
where printList :: Show a => [a] -> IO ()
printList = print
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment