Skip to content

Instantly share code, notes, and snippets.

@supki
Last active August 29, 2015 14:01
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 supki/2dd6da14c6d9535b3e28 to your computer and use it in GitHub Desktop.
Save supki/2dd6da14c6d9535b3e28 to your computer and use it in GitHub Desktop.
Crap
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE EmptyCase #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -Wall #-}
module Composers where
import Control.Applicative (Applicative(..), liftA2)
import GHC.Exts (Constraint)
type family ForEach (c :: (* -> *) -> Constraint) (fs :: [* -> *]) :: Constraint where
ForEach c '[] = ()
ForEach c (f ': fs) = (c f, ForEach c fs)
data Compose :: [* -> *] -> * -> * where
Pure :: a -> Compose '[] a
Compose :: f (Compose fs a) -> Compose (f ': fs) a
instance ForEach Functor fs => Functor (Compose fs) where
fmap :: (a -> b) -> Compose fs a -> Compose fs b
fmap f (Pure x) = Pure (f x)
fmap f (Compose g) = Compose (fmap (fmap f) g)
instance Applicative (Compose '[]) where
pure :: a -> Compose '[] a
pure = Pure
(<*>) :: Compose '[] (a -> b) -> Compose '[] a -> Compose '[] b
Pure f <*> Pure x = Pure (f x)
instance (ForEach Functor (f ': fs), Applicative f, Applicative (Compose fs)) => Applicative (Compose (f ': fs)) where
pure :: a -> Compose (f ': fs) a
pure = Compose . pure . pure
(<*>) :: Compose (f ': fs) (a -> b) -> Compose (f ': fs) a -> Compose (f ': fs) b
Compose f <*> Compose x = Compose (liftA2 (<*>) f x)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment