packages feed

guess-combinator-0.1: Guess/Combinator/Lib.hs

{-# LANGUAGE
  UndecidableInstances, IncoherentInstances,
  UnicodeSyntax, TypeOperators, ScopedTypeVariables, MultiParamTypeClasses,
  FunctionalDependencies, TypeSynonymInstances, FlexibleInstances, 
  FlexibleContexts #-}

module Guess.Combinator.Lib (module Prelude, module Data.HList, module Guess.Combinator.Lib) where

import Prelude (($), (++), show, Either(..), Maybe(..), Num(..), Show(..), Bool(..))
import Data.HList (HTrue, HFalse, HNil(HNil), HCons(HCons), (:*:), HAppend, HReverse)
import Data.HList.TypeCastGeneric2 (TypeCast)

-- | FunToList +type -typelist
-- Flatten the functions in a given type, in reverse order
-- 
-- For example, FunToList (a -> (b -> c) -> d) [d, [c, [b]], [a]]

class FunToList t tl | t → tl

instance (IsFunction t flag,
          FunToList' flag t tl)
         ⇒ FunToList t tl

class FunToList' a t tl | a t → tl

instance FunToList' HFalse t (t :*: HNil)

instance (FunToList x tlx,
          FunToList y tly,
          HAppend tly (tlx :*: HNil) tl) 
       ⇒ FunToList' HTrue (x → y) tl

-- | ListToFun +typelist -type
-- 
-- Reverse of FunToList

class ListToFun tl t | tl → t

instance ListToFun (t :*: HNil) t

instance (ListToFun tl a,
          ListToFun ((a → r) :*: tls) t)
         ⇒ ListToFun (r :*: (tl :*: tls)) t

-- Misc type-level programming classes and helpers

infixr 2 .*.
a .*. b = HCons a b

class IsFunction a b | a → b
instance TypeCast f HTrue ⇒ IsFunction (x → y) f
instance TypeCast f HFalse ⇒ IsFunction a f

class TypeEq' () x y b ⇒ TypeEq x y b | x y → b
class TypeEq' q x y b | q x y → b
class TypeEq'' q x y b | q x y → b
instance TypeEq' () x y b ⇒ TypeEq x y b
instance TypeCast b HTrue ⇒ TypeEq' () x x b
instance TypeEq'' q x y b ⇒ TypeEq' q x y b
instance TypeEq'' () x y HFalse

data Proxy t = Proxy