module Data.Thrist ( Thrist (..)
                   , foldThrist
                   , appendThrist ) where

import Prelude
import Data.Monoid
-- import Data.Char

data Thrist :: (* -> * -> *) -> * -> * -> * where
  Nil :: Thrist p a a
  Cons :: p a b -> Thrist p b c -> Thrist p a c

foldThrist :: (forall i j k . p i j -> p j k -> p i k) -> p c c -> Thrist p a c -> p a c
foldThrist _ v Nil = v
foldThrist f v (Cons h t) = h `f` (foldThrist f v t)

{- Simple demo:
t1 :: Thrist (->) Char Char
t1 = ord `Cons` ((\i -> i+32) `Cons` (chr `Cons` Nil))

t2 :: Char -> Char
t2 = foldThrist (flip (.)) id t1
-}

appendThrist :: forall (p :: * -> * -> *) a b c .
                Thrist p a b ->
                Thrist p b c ->
                Thrist p a c

appendThrist Nil a = a
appendThrist (Cons b r) a = Cons b (appendThrist r a)


instance Monoid (Thrist p a a) where
  mempty = Nil
  mappend = appendThrist