-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Functor combinators with tries & zippers -- -- Simple functor combinators, their derivatives, and their use for tries -- Maybe split out derivatives and/or tries later. @package functor-combo @version 0.0.2 -- | Standard building blocks for functors module FunctorCombo.Functor newtype Const a b :: * -> * -> * Const :: a -> Const a b getConst :: Const a b -> a -- | Empty/zero type constructor (no inhabitants) data Void a -- | Unit type constructor (one inhabitant) type Unit = Const () -- | Identity type constructor. Until there's a better place to find it. -- I'd use Control.Monad.Identity, but I don't want to introduce a -- dependency on mtl just for Id. newtype Id a :: * -> * Id :: a -> Id a unId :: Id a -> a inId :: (a -> b) -> Id a -> Id b inId2 :: (a -> b -> c) -> Id a -> Id b -> Id c -- | Sum on unary type constructors data (:+:) f g a InL :: (f a) -> :+: f g a InR :: (g a) -> :+: f g a eitherF :: (f a -> b) -> (g a -> b) -> (f :+: g) a -> b -- | Product on unary type constructors data (:*:) f g a (:*:) :: f a -> g a -> :*: f g a -- | Composition of unary type constructors -- -- There are (at least) two useful Monoid instances, so you'll -- have to pick one and type-specialize it (filling in all or parts of -- g and/or f). -- --
-- -- standard Monoid instance for Applicative applied to Monoid
-- instance (Applicative (g :. f), Monoid a) => Monoid ((g :. f) a) where
-- { mempty = pure mempty; mappend = liftA2 mappend }
-- -- Especially handy when g is a Monoid_f.
-- instance Monoid (g (f a)) => Monoid ((g :. f) a) where
-- { mempty = O mempty; mappend = inO2 mappend }
--
--
-- Corresponding to the first and second definitions above,
--
--
-- instance (Applicative g, Monoid_f f) => Monoid_f (g :. f) where
-- { mempty_f = O (pure mempty_f); mappend_f = inO2 (liftA2 mappend_f) }
-- instance Monoid_f g => Monoid_f (g :. f) where
-- { mempty_f = O mempty_f; mappend_f = inO2 mappend_f }
--
--
-- Similarly, there are two useful Functor instances and two
-- useful Cofunctor instances.
--
-- -- instance ( Functor g, Functor f) => Functor (g :. f) where fmap = fmapFF -- instance (Cofunctor g, Cofunctor f) => Functor (g :. f) where fmap = fmapCC -- -- instance (Functor g, Cofunctor f) => Cofunctor (g :. f) where cofmap = cofmapFC -- instance (Cofunctor g, Functor f) => Cofunctor (g :. f) where cofmap = cofmapCF ---- -- However, it's such a bother to define the Functor instances per -- composition type, I've left the fmapFF case in. If you want the fmapCC -- one, you're out of luck for now. I'd love to hear a good solution. -- Maybe someday Haskell will do Prolog-style search for instances, -- subgoaling the constraints, rather than just matching instance heads. newtype (:.) g :: (* -> *) f :: (* -> *) a :: (* -> *) -> (* -> *) -> * -> * O :: g (f a) -> :. a -- | Unwrap a '(:.)'. unO :: :. g f a -> g (f a) -- | Apply a unary function within the O constructor. inO :: (g (f a) -> g' (f' a')) -> :. g f a -> :. g' f' a' -- | Apply a binary function within the O constructor. inO2 :: (g (f a) -> g' (f' a') -> g'' (f'' a'')) -> :. g f a -> :. g' f' a' -> :. g'' f'' a'' -- | Add pre- and post processing (~>) :: (a' -> a) -> (b -> b') -> (a -> b) -> a' -> b' instance (Functor f, Functor g) => Functor (f :*: g) instance (Functor f, Functor g) => Functor (f :+: g) instance (Show (f a), Show (g a)) => Show ((:+:) f g a) instance (Show (f a), Show (g a)) => Show ((:*:) f g a) instance (Applicative f, Applicative g) => Applicative (f :*: g) instance Functor Void -- | Derivatives (one-hole contexts) for standard Functor combinators module FunctorCombo.Derivative -- | A derivative, i.e., a one-hole context for a container f (probably a -- functor). -- | Filling and extracting derivatives (one-hole contexts) module FunctorCombo.Holey -- | Location, i.e., one-hole context and a value for the hole. type Loc f a = (Der f a, a) -- | Filling and creating one-hole contexts class (Functor f) => Holey f fill :: (Holey f) => Loc f a -> f a extract :: (Holey f) => f a -> f (Loc f a) instance (Holey f, Holey g) => Holey (g :. f) instance (Holey f, Holey g) => Holey (f :*: g) instance (Holey f, Holey g) => Holey (f :+: g) instance Holey Id instance Holey (Const z) -- | Filling and extracting derivatives (one-hole contexts) module FunctorCombo.DHoley class (Functor f) => Holey f where { type family Der f :: * -> *; } fill :: (Holey f) => Loc f a -> f a extract :: (Holey f) => f a -> f (Loc f a) instance (Holey f, Holey g) => Holey (g :. f) instance (Holey f, Holey g) => Holey (f :*: g) instance (Holey f, Holey g) => Holey (f :+: g) instance Holey Id instance Holey (Const z) -- | Zippers for functor fixpoints module FunctorCombo.FixC -- | Context for functor fixpoints type FixC f = [Der f (Fix f)] type LocFix f = (FixC f, Fix f) up :: (Holey f) => LocFix f -> LocFix f down :: (Holey f) => LocFix f -> f (LocFix f) -- | Regular data types module FunctorCombo.Regular class (Functor (PF t)) => Regular t where { type family PF t :: * -> *; } wrap :: (Regular t) => PF t t -> t unwrap :: (Regular t) => t -> PF t t instance Regular (Tree a) instance Regular [a] module FunctorCombo.LocT type Context t = [Der (PF t) t] type LocT t = (Context t, t) up :: (Regular t, Holey (PF t)) => LocT t -> LocT t down :: (Regular t, Holey (PF t)) => LocT t -> PF t (LocT t) -- | Functor-based memo tries (strict for now) module FunctorCombo.MemoTrie -- | Domain types with associated memo tries class HasTrie k where { type family Trie k :: * -> *; } trie :: (HasTrie k) => (k -> v) -> (k :->: v) untrie :: (HasTrie k) => (k :->: v) -> (k -> v) enumerate :: (HasTrie k) => (k :->: v) -> [(k, v)] -- | Trie-based function memoizer memo :: (HasTrie k) => Unop (k -> v) -- | Memoize a binary function, on its first argument and then on its -- second. Take care to exploit any partial evaluation. memo2 :: (HasTrie s, HasTrie t) => Unop (s -> t -> a) -- | Memoize a ternary function on successive arguments. Take care to -- exploit any partial evaluation. memo3 :: (HasTrie r, HasTrie s, HasTrie t) => Unop (r -> s -> t -> a) instance (HasTrie a, HasTrie (a :->: b)) => HasTrie (a -> b) instance HasTrie Integer instance HasTrie Int instance (HasTrie (PF (Tree a) (Tree a) :->: v)) => HasTrie (TreeTrie a v) instance (HasTrie a) => HasTrie (Tree a) instance (HasTrie (PF [a] [a] :->: v)) => HasTrie (ListTrie a v) instance (HasTrie a) => HasTrie [a] instance (HasTrie (g (f a))) => HasTrie ((:.) g f a) instance (HasTrie (f a), HasTrie (g a)) => HasTrie ((:+:) f g a) instance (HasTrie (f a), HasTrie (g a)) => HasTrie ((:*:) f g a) instance (HasTrie a) => HasTrie (Id a) instance (HasTrie x) => HasTrie (Const x a) instance (HasTrie a, HasTrie b, HasTrie c, HasTrie d) => HasTrie (a, b, c, d) instance (HasTrie a, HasTrie b, HasTrie c) => HasTrie (a, b, c) instance HasTrie Bool instance (HasTrie a, HasTrie b) => HasTrie (a, b) instance (HasTrie a, HasTrie b) => HasTrie (Either a b) instance HasTrie ()