ZipFold-0.1.4: src/Data/WithCont.hs
{-# LANGUAGE ExistentialQuantification, FlexibleContexts #-}
{-# OPTIONS_GHC -Wall #-}
----------------------------------------------------------------------
-- |
-- Module : Data.WithCont
-- Copyright : (c) Conal Elliott 2009
-- License : BSD3
--
-- Maintainer : conal@conal.net
-- Stability : experimental
--
-- Add continuation
----------------------------------------------------------------------
module Data.WithCont (WithCont(..)) where
import Prelude hiding (zip)
import Control.Arrow
import Control.Applicative
import Data.Zip
-- | Add a continuation.
data WithCont z c = forall a. WC (z a) (a -> c)
-- TODO: generalize the continuation to an arbitrary arrow.
instance Functor (WithCont z) where
fmap g (WC f k) = WC f (arr k >>> g)
instance Zip z => Zip (WithCont z) where
WC fa ka `zip` WC fb kb =
WC (fa `zip` fb) (ka *** kb)
-- TODO: merge unit into Zip
--- Another interface:
class (Functor f, Zip f) => Monoidal f where
unit :: f ()
instance Monoidal ((->) a) where unit = const ()
instance Zip z => Monoidal (WithCont z) where
unit = WC (error "unneeded pre-cont") unit
-- Standard Applicative instance for |Monoidal|
instance Zip z => Applicative (WithCont z) where
pure a = fmap (const a) unit
wf <*> wx = app <$> (wf `zip` wx)
--------------------
-- A lazy (~) pattern cannot bind existential type variables
--
-- instance Functor (WithCont z) where
-- fmap g ~(WC f k) = WC f (fmap g k)
-- My brain just exploded.
-- I can't handle pattern bindings for existentially-quantified constructors.
-- Instead, use a case-expression, or do-notation, to unpack the constructor.
-- instance Zip (z) => Applicative (WithCont z) where
-- pure a = WC (error "unneeded pre-cont") (pure a)
-- WC hf hk <*> WC xf xk =
-- WC (hf `zip` xf) (\ (a,a') -> (hk a) (xk a'))
-- instance Functor (WithCont z) where
-- fmap g = \ (WC f k) -> WC f (fmap g k)
-- instance Zip (z) => Applicative (WithCont z) where
-- pure a = WC (error "unneeded pre-cont") (pure a)
-- ~(WC hf hk) <*> ~(WC xf xk) =
-- WC (hf `zip` xf) (\ (a,a') -> (hk a) (xk a'))
-- instance Zip (z) => Applicative (WithCont z) where
-- pure a = WC (error "unneeded pre-cont") (pure a)
-- (<*>) = \ (WC hf hk) (WC xf xk) ->
-- WC (hf `zip` xf) (\ (a,a') -> (hk a) (xk a'))