{-# LANGUAGE GADTs, DataKinds, KindSignatures, FlexibleInstances #-}
module Nlist where
data Flag = Empty | NonEmpty
-- data List f a = Nil | Cons a (List f a)
data List (f :: Flag) a where
Nil :: List Empty a
Cons :: a -> (List f a) -> List NonEmpty a
instance (Show a) => (Show (List f a)) where
show Nil = "Nil"
show (Cons x xs) = undefined
safeHead :: List NonEmpty a -> a
safeHead (Cons a _) = a
instance Functor (List f) where
-- fmap :: (a -> b) -> List f a -> List f b
fmap f (Cons x xs) = Cons (f x) (fmap f xs)
fmap f Nil = Nil
fold :: (a -> b -> b) -> b -> List f a -> b
fold c n Nil = n
fold c n (Cons x xs) = c x (fold c n xs)
nfilter :: a -> (a -> Bool) -> List f a -> List NonEmpty a
nfilter a f Nil = (Cons a Nil)
nfilter a f (Cons x xs) = if f x then Cons x (nfilter a f xs) else nfilter a f xs
x = safeHead (fmap (+1) (Cons 1 Nil))