diff --git a/CHANGES b/CHANGES
--- a/CHANGES
+++ b/CHANGES
@@ -1,28 +1,48 @@
-Version 0.2:
-* Simplified exports in src/Interface/TV.hs.  Now just exports by module
-  rather than by entity.  Also re-export DeepArrow modules.
-* Moved GUI functionality out to a new package "GuiTV".  Removed
-  dependency on Phooey and (indirectly) wxHaskell, as the latter can be
-  difficult to install.
+% [TV](http://haskell.org/haskellwiki/TV) changes
 
-Version 0.1.1:
-* Changed all files to *nix-style line endings.
+## Version 0.3 ##
 
-Version 0.1:
-* Removed iEmpty & iEmpty and corresponding constructors. Generate dynamic
-  errors earlier rather than later.
-* Removed ICompose & OCompose constructors.  Redefined iCompose and
-  oCompose (and consequently fmap on inputs and cofmap on outputs) to work
-  only on (possibly titled) primitives.  I don't know how to implement the
-  DeepArrow algebra with OCompose.
-* Added wrapO and wrapAO, sort of analogous (or dual) to wrapF.  I'm not
-  sure the name is a great choice.  I've also considered "unwrapO".
-* Added readShow, defined via wrapO.
-* Redefined interactRSOut via readShow and renamed "interactLineRS".
-  Added "interactRS".
-* Added fromFile & toFile TV functions.
-* Added fileOut
-* Moved Grading example from src/Examples.hs to src/Grading.hs
-* Added "short lines" example to src/Examples.hs.
-* Added type alias RunTV for defining types of runTV specializations, such
-  as runUI and runIO.
++  Overhauled to integrate with [Eros](http://haskell.org/haskellwiki/Eros)
++  Eliminated arrows, in favor of [applicative
+   functors](http://haskell.org/haskellwiki/Applicative_functor).  Now
+   [Input](src/Interface/TV/Input.hs) takes a type (constructor) parameters:
+   `src`, and [Output](src/Interface/TV/Output.hs) takes two type
+   (constructor) parameters: `src` & `snk`.
++  Using `LANGUAGE` pragma in place of most `OPTIONS`
+
+## Version 0.2 ##
+
++  Simplified exports in [TV.hs](src/Interface/TV.hs).  Now just exports by module
+   rather than by entity.  Also re-export [DeepArrow] modules.
++  Moved GUI functionality out to a new package [GuiTV].  Removed
+   dependency on [Phooey] and (indirectly) [wxHaskell], as the latter can
+   be difficult to install. 
+
+## Version 0.1.1 ##
+
++  Changed all files to *nix-style line endings.
+
+## Version 0.1 ##
+
++  Removed iEmpty & oEmpty and corresponding constructors. Generate dynamic
+   errors earlier rather than later.
++  Removed ICompose & OCompose constructors.  Redefined iCompose and
+   oCompose (and consequently fmap on inputs and cofmap on outputs) to work
+   only on (possibly titled) primitives.  I don't know how to implement the
+   DeepArrow algebra with OCompose.
++  Added wrapO and wrapAO, sort of analogous (or dual) to wrapF.  I'm not
+   sure the name is a great choice.  I've also considered "unwrapO".
++  Added readShow, defined via wrapO.
++  Redefined interactRSOut via readShow and renamed "interactLineRS".
+   Added "interactRS".
++  Added fromFile & toFile TV functions.
++  Added fileOut
++  Moved Grading example from src/Examples.hs to src/Grading.hs
++  Added "short lines" example to src/Examples.hs.
++  Added type alias RunTV for defining types of runTV specializations, such
+   as runUI and runIO.
+
+[GuiTV]:      http://haskell.org/haskellwiki/GuiTV
+[Phooey]:     http://haskell.org/haskellwiki/Phooey
+[wxHaskell]:  http://haskell.org/haskellwiki/wxHaskell
+
diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -1,12 +1,8 @@
-# See README for Cabal-based building.  Other fancy stuff (like haddock) here.
+# For special configuration, especially for docs.  Otherwise see README.
 
-user = conal
+# haddock-interfaces=\
+#   http://haskell.org/ghc/docs/latest/html/libraries/base,c:/ghc/ghc-6.6/doc/html/libraries/base/base.haddock \
+#   http://haskell.org/ghc/docs/latest/html/libraries/mtl,c:/ghc/ghc-6.6/doc/html/libraries/mtl/mtl.haddock \
+#   http://darcs.haskell.org/packages/DeepArrow/doc/html,c:/Haskell/packages/DeepArrow-0.0.1/doc/html/DeepArrow.haddock
 
-configure_args=--disable-use-packages --haddock-args="\
-  --read-interface=http://haskell.org/ghc/docs/latest/html/libraries/base,c:/ghc/ghc-6.6/doc/html/libraries/base/base.haddock \
-  --read-interface=http://haskell.org/ghc/docs/latest/html/libraries/mtl,c:/ghc/ghc-6.6/doc/html/libraries/mtl/mtl.haddock \
-  --read-interface=http://darcs.haskell.org/packages/DeepArrow/doc/html,c:/Haskell/packages/DeepArrow-0.0/doc/html/DeepArrow.haddock \
-  $(source_args)\
-  $(comments_args)\
-  "
 include ../my-cabal-make.inc
diff --git a/Setup.lhs b/Setup.lhs
--- a/Setup.lhs
+++ b/Setup.lhs
@@ -1,3 +1,3 @@
-#!/usr/bin/env runhaskell
-> import Distribution.Simple
+#!/usr/bin/env runhaskell
+> import Distribution.Simple
 > main = defaultMain
diff --git a/TV.cabal b/TV.cabal
--- a/TV.cabal
+++ b/TV.cabal
@@ -1,5 +1,5 @@
 Name:                TV
-Version:             0.2
+Version:             0.4
 Synopsis:	     Tangible Values -- composable interfaces
 Category:            Interfaces
 Description:
@@ -25,22 +25,18 @@
 License:             BSD3
 Stability:	     experimental
 Hs-Source-Dirs:      src
-Build-Depends:       base, mtl, DeepArrow
+Build-Depends:       base, DeepArrow, TypeCompose >= 0.2
 tested-with:	     GHC==6.6
-Extensions:          CPP
+build-type:	     Simple
 Exposed-Modules:     
                      Interface.TV
                      Interface.TV.Input
                      Interface.TV.Output
                      Interface.TV.Tangible
-                     Interface.TV.Present
                      Interface.TV.OFun
                      Interface.TV.Common
-                     Interface.TV.Defaults
-                     Interface.TV.Kleisli
                      Interface.TV.IO
-                     Interface.TV.Misc
+                     Interface.TV.Defaults
 Extra-Source-Files:  
-                     Interface.TV.DefaultsList
                      Examples
-ghc-options:         -O -W
+ghc-options:         -W
diff --git a/src/Examples.hs b/src/Examples.hs
--- a/src/Examples.hs
+++ b/src/Examples.hs
@@ -1,32 +1,57 @@
-{-# OPTIONS -fglasgow-exts #-}
+{-# LANGUAGE OverlappingInstances, UndecidableInstances
+           , IncoherentInstances, FlexibleContexts #-}
+-- For ghc 6.6 compatibility
+-- {-# OPTIONS -fglasgow-exts #-}
 
+---- Some TV examples.  See also GuiTV.
+
 module Examples where
 
 import Data.List (sort)
+import Control.Compose (cofmap,OI)
+import Control.Arrow.DeepArrow ((->|))
 
--- import Control.Arrow.DeepArrow
--- import Data.FunArr
+-- TypeCompose
+import Data.Title
+
 import Interface.TV
 
+-- To pick up the FunArr instance for OFun.  GHC bug.
+import Interface.TV.OFun()
+
 -- Try out these the examples with runIO.  For the explicitly IO-typed examples, you
--- can use runIO or runTV.
+-- can use either runIO or runTV.
 
-reverseT :: DefaultOut ([a] -> [a]) => CTV ([a] -> [a])
-reverseT = tv (oTitle "reverse" defaultOut) reverse
+reverseT :: CTV (String -> String)
+reverseT = tv (title "reverse" defaultOut) reverse
 
+-- I don't know why this more general version fails.
+-- 
+--   reverseT :: ( Read a, Show a , CommonIns src , CommonOuts snk ) =>
+--               TV src snk ([a] -> [a])
+--
+-- GHC wants to use the [a] rather than the String instances of DefaultIn
+-- and DefaultOut.  I thought the rule is most specific instance wins.
+
 --  This one reverses twice
 revTwice :: CTV (String -> String)
 revTwice = reverseT ->| reverseT
 
+-- Same problem with more general type:
+--   revTwice :: (Read a, Show a, CommonIns src, CommonOuts snk) =>
+--               TV src snk ([a] -> [a])
+
+
+
 ---- IO examples
 
-testO :: Output KIO (String -> String)
+testO :: Output IO OI (String -> String)
 testO = oLambda (fileIn "test.txt") defaultOut
 
 -- Apply a function on the lines or on the words of a string.
 onLines, onWords :: ([String] -> [String]) -> (String -> String)
-onLines = wrapF unlines lines
-onWords = wrapF unwords words
+onLines f = unlines . f . lines
+onWords f = unwords . f . words
 
 perLine,perWord :: (String -> String) -> (String -> String)
 perLine f = onLines (map f)
@@ -49,13 +74,13 @@
   where tween lo hi i = lo <= i && i < hi
 
 -- Extract lines from a file before a function and combine lines after.
-shortO :: FilePath -> Output KIO ([String] -> [String])
+shortO :: FilePath -> Output IO OI ([String] -> [String])
 shortO path = oLambda (fmap lines (fileIn path)) (cofmap unlines defaultOut)
 
 -- Nearly equivalent, but retains more Output structure:
 -- shortO path = cofmap (wrapF unlines lines) (oLambda (fileIn path) defaultOut)
 
-shortT :: FilePath -> Int -> TV KIO ([String] -> [String])
+shortT :: FilePath -> Int -> TV IO OI ([String] -> [String])
 shortT path n = tv (shortO path) (sort . short n)
 
 -- Example: runTV (shortT "c:/conal/Misc/quotes.tw" 100)
diff --git a/src/Grading.lhs b/src/Grading.lhs
--- a/src/Grading.lhs
+++ b/src/Grading.lhs
@@ -1,8 +1,8 @@
 ! Introduction /% -*-Twee-*- (http://www.gimcrackd.com/etc/src/twee.el) %/
-This post illustrates an approach to separating logic and IO using the [[TV| http://haskell.org/haskellwiki/TV]] library.  The example is [[from Don Stewart's blog| http://cgi.cse.unsw.edu.au/~dons/blog/2006/12/16#programming-haskell-intro]]. My thanks to Don, as this example inspired me to play with alternatives, which led to generalizing TV from GUIs to a more general notion of "interfaces". The TV approach clarifies the pure logic part and the IO part and is more conveniently composable than the mixed logic/IO formulation.
+The example in this post illustrates an approach to separating logic and IO using the [[TV| http://haskell.org/haskellwiki/TV]] library.  The example is [[from Don Stewart's blog| http://cgi.cse.unsw.edu.au/~dons/blog/2006/12/16#programming-haskell-intro]]. My thanks to Don, as this example inspired me to play with alternatives, which led to generalizing TV from GUIs to a more general notion of "interfaces". The TV approach clarifies the pure logic part and the IO part and is more conveniently composable than the mixed logic/IO formulation.
 
 ! What's this?
-This post is a literate Haskell program, as well as a TiddlyWiki passage (tiddler).  To run the program, double-click on the entry, copy the markup into file called "Grading.lhs", install [[TV| http://haskell.org/haskellwiki/TV]] 0.1 or later (and the libraries TV [[depends on| http://darcs.haskell.org/packages/TV/TV.cabal]]).
+This post is a literate Haskell program, as well as a TiddlyWiki passage (tiddler).  To run the program, double-click on the entry, copy the markup into file called "Grading.lhs", install [[TV| http://haskell.org/haskellwiki/TV]] 0.1 or later (and the libraries on which TV [[depends| http://darcs.haskell.org/packages/TV/TV.cabal]]).  I recommend TV 0.2 or later, which does not require GUI support (moved out to [[GuiTV| http://haskell.org/haskellwiki/GuiTV]]).
 
 In the text below, you can click boxed ">" symbols to show more detail and click boxed "<" symbols to show less detail.  For example, we begin with a module header. +++
 \begin{code}
@@ -12,7 +12,8 @@
 import Data.Map (Map,empty,keys,insertWith,findWithDefault)
 import Text.Printf
 
-import Interface.TV -- 0.1 or later
+import Interface.TV
+import Interface.TV.OFun()  -- work around GHC bug.  ticket #1145
 \end{code}
 === 
 
@@ -67,8 +68,7 @@
 \begin{code}
 gradingStrOut = oLambda (fileIn "tasks") stringOut
 \end{code}
-The TV functions @fileIn@ and @stringOut@ are trivial wrappers around
-@readFile@ and @putStr@.
+The TV functions @fileIn@ and @stringOut@ are trivial wrappers around @readFile@ and @putStr@.
 
 Combining this interface with the pure value, we get a "TV" (tangible value):
 \begin{code}
diff --git a/src/Interface/TV.hs b/src/Interface/TV.hs
--- a/src/Interface/TV.hs
+++ b/src/Interface/TV.hs
@@ -1,10 +1,8 @@
-{-# OPTIONS -fglasgow-exts #-}
-
 ----------------------------------------------------------------------
 -- |
 -- Module      :  Interface.TV
 -- Copyright   :  (c) Conal Elliott 2006
--- License     :  LGPL
+-- License     :  BSD3
 -- 
 -- Maintainer  :  conal@conal.net
 -- Stability   :  experimental
@@ -22,24 +20,14 @@
   , module Interface.TV.Output
   -- | Tangible values -- interface (output) and value, combined & separable
   , module Interface.TV.Tangible
-  -- | Convert inputs and outputs to arrow values
-  , module Interface.TV.Present
   -- | Output transformations, as a deep arrow.
   , module Interface.TV.OFun
   -- | Some common interaction vocabulary 
   , module Interface.TV.Common
   -- | Default inputs & outputs
   , module Interface.TV.Defaults
-  -- | Monadic TVs, via Kleisli arrows
-  , module Interface.TV.Kleisli
-  -- | IO-based instances of TV classes
+  -- | Support for IO-based TVs
   , module Interface.TV.IO
-  -- | Miscellaneous helpers
-  , module Interface.TV.Misc
-  -- | Re-exports from DeepArrow
-  , module Control.Arrow.DeepArrow
-  , module Data.FunArr
-
   ) where
 
 -- import Graphics.UI.Phooey (UI)
@@ -47,13 +35,7 @@
 import Interface.TV.Input
 import Interface.TV.Output
 import Interface.TV.Tangible
-import Interface.TV.Present
 import Interface.TV.OFun
 import Interface.TV.Common
 import Interface.TV.Defaults
-import Interface.TV.Kleisli
 import Interface.TV.IO
-import Interface.TV.Misc
-
-import Control.Arrow.DeepArrow
-import Data.FunArr
diff --git a/src/Interface/TV/Common.hs b/src/Interface/TV/Common.hs
--- a/src/Interface/TV/Common.hs
+++ b/src/Interface/TV/Common.hs
@@ -1,14 +1,17 @@
-{-# OPTIONS -fglasgow-exts #-}
+{-# LANGUAGE Rank2Types, TypeOperators, TypeSynonymInstances,
+    PatternGuards, FlexibleInstances #-}
+-- For ghc 6.6 compatibility
+-- {-# OPTIONS -fglasgow-exts #-}
 
 ----------------------------------------------------------------------
 -- |
 -- Module      :  Interface.TV.Common
 -- Copyright   :  (c) Conal Elliott 2006
--- License     :  LGPL
+-- License     :  BSD3
 -- 
 -- Maintainer  :  conal@conal.net
 -- Stability   :  experimental
--- Portability :  portable
+-- Portability :  Rank2Types
 -- 
 -- Some common interaction vocabulary 
 ----------------------------------------------------------------------
@@ -16,74 +19,109 @@
 module Interface.TV.Common
   (
   -- * Type class
-   CommonInsOuts(..), Common, CInput, COutput, CTV
+   CommonIns(..), readD, getReadF, CommonOuts(..), putShowC
+  , CInput, CInputI, COutput, CTV
   -- * Inputs
   , stringIn, boolIn, readIn  -- , intIn
   -- * Outputs
   , stringOut, boolOut, showOut, interactLine, readShow, interactLineRS
   ) where
 
-import Control.Arrow
+-- import Control.Arrow
+-- import Control.Applicative
 
+import Control.Compose (OI,Flip(..),Cofunctor(..))
+
 import Interface.TV.Input
 import Interface.TV.Output
 import Interface.TV.OFun (wrapO)
 import Interface.TV.Tangible (TV)
 
-import Interface.TV.Misc (readD,Cofunctor(..))
+-- import Interface.TV.Misc (readD)
 
--- | This class captures some useful operations available in some arrows
--- and allows definition of some \"'Common'\" 'Input's, 'Output's, and
--- TVs.
-class Arrow (~>) => CommonInsOuts (~>) where
-  -- | Output a string
-  putString :: String ~> ()
-  -- | Input a string
-  getString :: () ~> String
-  -- | Output a bool
-  putBool :: Bool ~> ()
-  putBool = pure show >>> putString
+
+-- | This class captures some useful operations available in some input
+-- types, and allows definition of some \"'Common'\" 'Input's
+class CommonIns src where
+  -- | Input a string (with default)
+  getString :: String -> src String
+  -- | Read-based input.  Initial value is also used as a default for
+  -- failed parse.  Define as 'getReadF' when @src@ is a 'Functor'.
+  -- Requires 'Show' as well as 'Read', for displaying the initial value.
+  getRead :: (Show a, Read a) => a -> src a
   -- | Input a bool
-  getBool :: Bool               -- ^ default
-          -> () ~> Bool
-  getBool dflt = getString >>> pure (readD dflt)
+  getBool :: Bool -> src Bool
+  getBool = getRead
 {-
   -- | Input an int with default & bounds
   -- TODO: add getDouble or generalize
   getInt :: Int                 -- ^ default
          -> (Int,Int)           -- ^ bounds
-         -> () ~> Int
+         -> src Int
 -}
 
--- | For operations over all 'CommonInsOuts' arrows.
-type Common f a = forall (~>). CommonInsOuts (~>) => f (~>) a
 
--- | Inputs that work over all 'CommonInsOuts' arrows.
-type CInput a = Common Input a
+-- | Read with default value.  If the input doesn't parse as a value of
+-- the expected type, or it's ambiguous, yield the default value.
+readD :: Read a => a -> String -> a
+readD dflt str | [(a,"")] <- reads str = a
+               | otherwise             = dflt
 
--- | Outputs that work over all 'CommonInsOuts' arrows.
-type COutput a = Common Output a
+-- | 'getRead' for 'Functor's
+getReadF :: (CommonIns src, Functor src, Show a, Read a) => a -> src a
+getReadF dflt = fmap (readD dflt) (getString (show dflt))
 
--- | Convenient type synonym for TVs that work over all 'CommonInsOuts' arrows.
-type CTV a = Common TV a
 
--- | String input
-stringIn :: CInput String
-stringIn = iPrim getString
+instance CommonIns IO where { getString = const getLine; getRead = getReadF }
 
--- | Bool input
-boolIn :: Bool                          -- ^ default
-       -> CInput Bool
-boolIn dflt = iPrim (getBool dflt)
+instance CommonOuts OI where { putString = Flip putStrLn; putShow = putShowC }
 
+-- Hm.  putStrLn vs putStr above?
+
+-- | This class captures some useful operations available in some arrows
+-- and allows definition of some \"'Common'\" 'Input's, 'Output's, and
+-- TVs.
+class CommonOuts snk where
+  -- | Output a string
+  putString :: snk String
+  -- | Shows based outout.  Define as 'putReadC' when @snk@ is a
+  -- 'Cofunctor'
+  putShow :: Show a => snk a
+  -- | Output a bool
+  putBool :: snk Bool
+  putBool = putShow
+
+putShowC :: (CommonOuts snk, Cofunctor snk, Show a) => snk a
+putShowC = cofmap show putString
+
+-- | Inputs that work over all 'CommonInsOuts' typecons.
+type CInput a = forall src. (CommonIns src) => Input src a
+
+-- | 'CInput' with initial value
+type CInputI a = a -> CInput a
+
+-- | Outputs that work over all 'CommonOuts' typecons.
+type COutput a =
+  forall src snk. (CommonIns src, CommonOuts snk) => Output src snk a
+
+-- | Convenient type synonym for TVs that work over all 'CommonInsOuts' typecons.
+type CTV a = forall src snk. (CommonIns src, CommonOuts snk) => TV src snk a
+
+-- | String input with default
+stringIn :: CInputI String
+stringIn s = iPrim (getString s)
+
+-- | Bool input with default
+boolIn :: CInputI Bool
+boolIn b = iPrim (getBool b)
+
 -- -- | Int input, with default and bounds
 -- intIn :: Int -> (Int,Int) -> CInput Int
 -- intIn dflt bounds = iPrim (getInt dflt bounds)
 
 -- | Input a readable value.  Use default when read fails.
-readIn :: Read a => a                   -- ^ default
-       -> CInput a
-readIn dflt = fmap (readD dflt) stringIn
+readIn :: (Read a, Show a) => CInputI a
+readIn a = iPrim (getRead a)
 
 
 -- | Output a string
@@ -96,27 +134,39 @@
 
 -- | Output a showable value
 showOut :: Show a => COutput a
-showOut = cofmap show stringOut
+showOut = oPrim putShow -- cofmap show stringOut
 
 -- | 'Output' version of 'interact'.  Well, not quite, since the IO
 -- version uses 'getLine' instead of 'getContents'.  See also
 -- 'Interface.TV.interactOut'
-interactLine :: COutput (String -> String)
-interactLine = oLambda stringIn stringOut
+interactLine :: String -> COutput (String -> String)
+interactLine s = oLambda (stringIn s) stringOut
 
 -- | Handy Read+Show wrapper
-readShow :: (Read a, Show b, CommonInsOuts (~>))
-         => Output (~>) (String->String) -- ^ base output
+readShow :: ( Read a, Show b, CommonIns src, CommonOuts snk
+            , Functor src, Cofunctor snk )
+         => Output src snk (String->String) -- ^ base output
          -> a                            -- ^ default, when read fails
-         -> Output (~>) (a -> b)
+         -> Output src snk (a -> b)
+
 readShow o dflt = wrapO show (readD dflt) o
 
+-- Tempting to give the following terse type spec:
+-- 
+-- readShow :: (Read a, Show b) =>
+--             CFOutput (String->String) -> a -> CFOutput (a -> b)
+--
+-- However, the universality requirement on the first argument is too strong.
+
+
+
 -- | Read+Show of 'interactLine'
-interactLineRS :: (Read a, Show b, CommonInsOuts (~>))
+interactLineRS :: ( Read a, Show a, Show b, CommonIns src, CommonOuts snk )
                => a                     -- ^ default, if read fails
-               -> Output (~>) (a -> b)
-interactLineRS = readShow interactLine
+               -> Output src snk (a -> b)
 
--- Equivalently:
---  interactLineRS dflt = wrapO show (readD dflt) interactLine
---  interactLineRS dflt = oLambda (readIn dflt) showOut
+interactLineRS dflt = oLambda (readIn dflt) showOut
+
+-- This version requires Functor src & Cofunctor snk
+--  interactLineRS a = readShow (interactLine (show a)) a
+
diff --git a/src/Interface/TV/Defaults.hs b/src/Interface/TV/Defaults.hs
--- a/src/Interface/TV/Defaults.hs
+++ b/src/Interface/TV/Defaults.hs
@@ -1,10 +1,14 @@
-{-# OPTIONS -fglasgow-exts #-}
+{-# LANGUAGE MultiParamTypeClasses, OverlappingInstances
+           , TypeSynonymInstances, FlexibleInstances, UndecidableInstances
+           , IncoherentInstances #-}
+-- For ghc 6.6 compatibility
+-- {-# OPTIONS -fglasgow-exts -fallow-overlapping-instances -fallow-incoherent-instances #-}
 
 ----------------------------------------------------------------------
 -- |
 -- Module      :  Interface.TV.Defaults
 -- Copyright   :  (c) Conal Elliott 2006
--- License     :  LGPL
+-- License     :  BSD3
 -- 
 -- Maintainer  :  conal@conal.net
 -- Stability   :  experimental
@@ -34,37 +38,47 @@
 ----------------------------------------------------------}
 
 -- | Class of types that provide a default input
-class DefaultIn a where
+class DefaultIn src a where
   -- | The default input for a type
-  defaultIn :: CInput a
+  defaultIn :: Input src a
 
-instance DefaultIn Bool   where defaultIn = boolIn False
-instance DefaultIn Int    where defaultIn = readIn 0
-instance DefaultIn Double where defaultIn = readIn 0
-instance DefaultIn Float  where defaultIn = readIn 0
-instance DefaultIn String where defaultIn = stringIn
+instance CommonIns src => DefaultIn src Bool   where defaultIn = boolIn False
+instance CommonIns src => DefaultIn src Int    where defaultIn = readIn 0
+instance CommonIns src => DefaultIn src Double where defaultIn = readIn 0
+instance CommonIns src => DefaultIn src Float  where defaultIn = readIn 0
+instance CommonIns src => DefaultIn src String where defaultIn = stringIn ""
 
-instance (DefaultIn a, DefaultIn b) => DefaultIn (a,b) where
+instance (DefaultIn src a, DefaultIn src b) => DefaultIn src (a,b) where
   defaultIn = IPair defaultIn defaultIn
 
+instance (Read a, Show a, CommonIns src, DefaultIn src a) => DefaultIn src [a] where
+  defaultIn = readIn []
 
+
 {----------------------------------------------------------
     Outputs
 ----------------------------------------------------------}
 
 -- | Class of types that provide a default output
-class DefaultOut a where
+class DefaultOut src snk a where
   -- | The default output for a type
-  defaultOut :: COutput a
+  defaultOut :: Output src snk a
 
-instance DefaultOut Bool   where defaultOut = boolOut
-instance DefaultOut Int    where defaultOut = showOut
-instance DefaultOut Double where defaultOut = showOut
-instance DefaultOut Float  where defaultOut = showOut
-instance DefaultOut String where defaultOut = stringOut
+instance (CommonIns src, CommonOuts snk) => DefaultOut src snk Bool   where defaultOut = boolOut
+instance (CommonIns src, CommonOuts snk) => DefaultOut src snk Int    where defaultOut = showOut
+instance (CommonIns src, CommonOuts snk) => DefaultOut src snk Double where defaultOut = showOut
+instance (CommonIns src, CommonOuts snk) => DefaultOut src snk Float  where defaultOut = showOut
+instance (CommonIns src, CommonOuts snk) => DefaultOut src snk String where defaultOut = stringOut
 
-instance (DefaultOut a, DefaultOut b) => DefaultOut (a,b) where
+-- The OverlappingInstances, UndecidableInstances, and IncoherentInstances
+-- are all for the overlap of String and lists.
+
+instance (DefaultOut src snk a, DefaultOut src snk b) => DefaultOut src snk (a,b) where
   defaultOut = OPair defaultOut defaultOut
 
-instance (DefaultIn a, DefaultOut b) => DefaultOut (a->b) where
+instance (DefaultIn src a, DefaultOut src snk b) => DefaultOut src snk (a->b) where
   defaultOut = OLambda defaultIn defaultOut
+
+instance (Show a, CommonIns src, CommonOuts snk, DefaultOut src snk a) =>
+    DefaultOut src snk [a] where
+  defaultOut = showOut
diff --git a/src/Interface/TV/DefaultsList.hs b/src/Interface/TV/DefaultsList.hs
deleted file mode 100644
--- a/src/Interface/TV/DefaultsList.hs
+++ /dev/null
@@ -1,128 +0,0 @@
-{-# OPTIONS -fglasgow-exts #-}
-
-----------------------------------------------------------------------
--- |
--- Module      :  Interface.TV.DefaultsList
--- Copyright   :  (c) Conal Elliott 2006
--- License     :  LGPL
--- 
--- Maintainer  :  conal@conal.net
--- Stability   :  experimental
--- Portability :  portable
--- 
--- Default inputs and outputs.  Experimental variant of
--- "Interface.TV.DefaultsList".
--- 
--- This version extend the 'DefaultIn' and 'DefaultOut' type classes to
--- handle lists in a general way, but still handle 'String' (@['Char']@)
--- in the most familiar way.  The 'Read' and 'Show' classes have a special
--- trick.  Can I adapt it?  This module is an incomplete first attempt.
--- See @error@ calls in the code for the gaps.
-
-----------------------------------------------------------------------
-
-module Interface.TV.DefaultsList
-  (
-  -- * Inputs
-   DefaultIn(..)
-  -- * Outputs
-  , DefaultOut(..)
-  ) where
-
-import Interface.TV.Input
-import Interface.TV.Output
-import Interface.TV.Common
-
-{----------------------------------------------------------
-    Inputs
-----------------------------------------------------------}
-
--- | Class of types that provide a default input
-class DefaultIn a where
-  -- | The default input for a type
-  defaultIn :: CInput a
-  -- | The default input for lists
-  defaultInList :: CInput [a]
-
-readInL :: Read a => CInput [a]
-readInL = readIn []
-
-instance DefaultIn Bool where
-  defaultIn     = boolIn False
-  defaultInList = readInL
-
-instance DefaultIn Char where
-  defaultIn     = readIn 'Q'
-  defaultInList = stringIn
-
-instance DefaultIn Int where
-  defaultIn     = readIn 0
-  defaultInList = readInL
-
-instance DefaultIn Double where
-  defaultIn     = readIn 0
-  defaultInList = readInL
-
-instance DefaultIn Float where
-  defaultIn     = readIn 0
-  defaultInList = readInL
-
--- instance DefaultIn String where
---   defaultIn     = stringIn
---   defaultInList = readInL
-
-instance DefaultIn a => DefaultIn [a] where
-  defaultIn     = defaultInList
-  defaultInList = error "defaultInList: not yet defined for [a]"
-
-instance (DefaultIn a, DefaultIn b) => DefaultIn (a,b) where
-  defaultIn     = IPair defaultIn defaultIn
-  defaultInList = error "defaultInList: not yet defined for (a,b)"
-
-{----------------------------------------------------------
-    Outputs
-----------------------------------------------------------}
-
--- | Class of types that provide a default output
-class DefaultOut a where
-  -- | The default output for a type
-  defaultOut :: COutput a
-  -- | The default output for lists
-  defaultOutList :: COutput [a]
-
-instance DefaultOut Bool where
-  defaultOut     = boolOut
-  defaultOutList = showOut
-
-instance DefaultOut Char where
-  defaultOut     = showOut
-  defaultOutList = stringOut
-
-instance DefaultOut Int where
-  defaultOut     = showOut
-  defaultOutList = showOut
-
-instance DefaultOut Double where
-  defaultOut     = showOut
-  defaultOutList = showOut
-
-instance DefaultOut Float where
-  defaultOut     = showOut
-  defaultOutList = showOut
-
--- instance DefaultOut String where
---   defaultOut     = stringOut
---   defaultOutList = showOut
-
-instance DefaultOut a => DefaultOut [a] where
-  defaultOut     = defaultOutList
-  defaultOutList = error "defaultOutList: not yet defined for [a]"
-
-instance (DefaultOut a, DefaultOut b) => DefaultOut (a,b) where
-  defaultOut     = OPair defaultOut defaultOut
-  defaultOutList = error "defaultOutList: not yet defined for (a,b)"
-
-instance (DefaultIn a, DefaultOut b) => DefaultOut (a->b) where
-  defaultOut     = OLambda defaultIn defaultOut
-  defaultOutList = error "defaultOutList: not yet defined for (a,b)"
-
diff --git a/src/Interface/TV/IO.hs b/src/Interface/TV/IO.hs
--- a/src/Interface/TV/IO.hs
+++ b/src/Interface/TV/IO.hs
@@ -1,25 +1,20 @@
-{-# OPTIONS -fglasgow-exts #-}
-
 ----------------------------------------------------------------------
 -- |
 -- Module      :  Interface.TV.IO
 -- Copyright   :  (c) Conal Elliott 2006
--- License     :  LGPL
+-- License     :  BSD3
 -- 
 -- Maintainer  :  conal@conal.net
 -- Stability   :  experimental
 -- Portability :  portable
 -- 
--- IO-based instances of TV classes 'PresentM', 'ToIOM', and
--- 'CommonInsOuts'
+-- Make IO play with TV
 ----------------------------------------------------------------------
 
 module Interface.TV.IO
   (
-  -- * Types
-   KIO
   -- * Inputs
-  , contentsIn, fileIn
+    contentsIn, fileIn
   -- * Outputs
   , interactOut, interactRS, fileOut
   -- * TVs
@@ -28,34 +23,21 @@
   , runIO
   ) where
 
-import Control.Arrow
+-- import Control.Arrow
 
+import Control.Compose (OI,Flip(..))
+-- import Data.Title (Title_f)
+-- import Data.Fun (Fun)
+import Control.Instances () -- for Monoid/IO instance
+
 import Interface.TV.Input
 import Interface.TV.Output
 import Interface.TV.Tangible (tv,TV,RunTV,runTV)
-import Interface.TV.Kleisli
-import Interface.TV.Common
+import Interface.TV.Common (stringIn,stringOut,readShow)
 
 
--- | Convenient shorthand for 'Kleisli IO'
-type KIO = Kleisli IO
-
--- There's not much to do here, given Kleisli
-
-instance PresentM IO where
-  presentTitleM str io = putStr (str ++ suffix) >> io
-   where
-     suffix | null str              = ""
-            | last str `elem` ".?:" = " "
-            | otherwise             = ": "
-
-instance ToIOM IO where toIOM = id
-
-instance CommonInsOuts KIO where
-  putString = Kleisli putStrLn          -- or putStr?
-  getString = Kleisli (const getLine)
-
---  getInt    = getIntKIO
+-- There's not much left to do here, given the IO instances for Title,
+-- Pair & Fun, CommonIns, CommonOuts.
 
 {-
 
@@ -70,51 +52,56 @@
 
 -}
 
+
+
+
 {----------------------------------------------------------
     Inputs
 ----------------------------------------------------------}
 
 -- | 'Input' version of 'getContents'
-contentsIn :: Input KIO String
-contentsIn = kIn getContents
+contentsIn :: Input IO String
+contentsIn = iPrim getContents
 
 -- | 'Input' version of 'readFile'
-fileIn :: FilePath -> Input KIO String
-fileIn name = kIn (readFile name)
+fileIn :: FilePath -> Input IO String
+fileIn name = iPrim (readFile name)
 
 {----------------------------------------------------------
     Outputs
 ----------------------------------------------------------}
 
 -- | Equivalent of 'interact'.  See also 'Interface.TV.interactLine'
-interactOut :: Output KIO (String -> String)
+interactOut :: Output IO OI (String -> String)
 interactOut = oLambda contentsIn stringOut
 
 -- | Read+Show of 'interact'
 interactRS :: (Read a, Show b)
            => a                         -- ^ default, if read fails
-           -> Output KIO (a -> b)
+           -> Output IO OI (a -> b)
+
 interactRS = readShow interactOut
 
 -- | 'Output' version of 'writeFile'
-fileOut :: FilePath -> Output KIO String
-fileOut name = kOut (writeFile name)
-
+fileOut :: FilePath -> Output IO OI String
+fileOut name = oPrim (Flip (writeFile name))
 
 {----------------------------------------------------------
     TVs
 ----------------------------------------------------------}
 
-fromFile :: FilePath -> TV KIO (String->String)
+-- | Identity function, with 'fileIn' and 'stringOut'
+fromFile :: FilePath -> TV IO OI (String->String)
 fromFile name = tv (oLambda (fileIn name) stringOut) id
 
-toFile :: FilePath -> TV KIO (String->String)
-toFile name = tv (oLambda stringIn (fileOut name)) id
+-- | Identity function, with stringIn' and 'fileOut'
+toFile :: FilePath -> TV IO OI (String->String)
+toFile name = tv (oLambda (stringIn "") (fileOut name)) id
 
 {----------------------------------------------------------
     Disambiguator
 ----------------------------------------------------------}
 
 -- | Type-disambiguating alias for 'runTV'
-runIO :: RunTV KIO
+runIO :: RunTV IO OI
 runIO = runTV
diff --git a/src/Interface/TV/Input.hs b/src/Interface/TV/Input.hs
--- a/src/Interface/TV/Input.hs
+++ b/src/Interface/TV/Input.hs
@@ -1,14 +1,17 @@
-{-# OPTIONS -fglasgow-exts -cpp #-}
+{-# LANGUAGE GADTs, KindSignatures #-}
+-- For ghc 6.6 compatibility
+-- {-# OPTIONS -fglasgow-exts #-}
 
+
 ----------------------------------------------------------------------
 -- |
 -- Module      :  Interface.TV.Input
--- Copyright   :  (c) Conal Elliott 2006
--- License     :  LGPL
+-- Copyright   :  (c) Conal Elliott 2007
+-- License     :  BSD3
 -- 
 -- Maintainer  :  conal@conal.net
 -- Stability   :  experimental
--- Portability :  portable
+-- Portability :  GADTs
 -- 
 -- Inputs -- means of obtaining values
 ----------------------------------------------------------------------
@@ -16,13 +19,16 @@
 module Interface.TV.Input
   (
   -- * Input data type
-    Input(..)
-  -- * Canonicalizers
+    Input(..), input
+  -- * Input functions
+  -- ** Builders
+  , iPrim, iPair, iTitle
+  -- ** Canonicalizers
   , asIPair
-  {-, iEmpty-}, iPrim, iPair, iCompose, iTitle
   ) where
 
-import Control.Arrow
+import Data.Pair  (Pair(..))
+import Data.Title (Title_f(..))
 
 {----------------------------------------------------------
     Input data type
@@ -30,48 +36,32 @@
 
 -- | An /Input/ describes a way to obtain a functional value from a user.
 -- Used in Output for making function visualizations.
-#ifdef __HADDOCK__
-data Input (~>) a
-#else
-data Input (~>) :: * -> * where
-  -- | When we don't know what input to use.   I might remove this constructor.
-  -- IEmpty :: Input (~>) a
+data Input src :: * -> * where
   -- | Input primitive
-  IPrim :: () ~> a -> Input (~>) a
+  IPrim :: src a -> Input src a
   -- | Input a pair
-  IPair :: Input (~>) a -> Input (~>) b -> Input (~>) (a,b)
+  IPair :: Input src a -> Input src b -> Input src (a,b)
   -- | Massage via an arrow value (generalizes fmap)
-  -- ICompose :: Input (~>) a -> a ~> b -> Input (~>) b
+  -- ICompose :: Input src a -> src (a -> b) -> Input src b
   -- | Title/label an input
-  ITitle :: String -> Input (~>) a -> Input (~>) a
-#endif
+  ITitle :: String -> Input src a -> Input src a
 
+instance Title_f (Input src) where title_f = iTitle
+
 -- See 'OEmpty' for note about eliminating OEmpty.
 
-instance Show (Input (~>) a) where
+instance Show (Input src a) where
   -- show IEmpty          = "IEmpty"
   show (IPrim _)       = "(IPrim _)"
   show (IPair a b)     = "(IPair "++show a++" "++show b++")"
   -- show (ICompose a _)  = "(ICompose "++show a++" _)"
   show (ITitle str i)  = "(ITitle "++show str++" "++show i++")"
 
-{----------------------------------------------------------
-    Canonicalizers
-----------------------------------------------------------}
-
--- | Dissect a pair-valued input into two inputs.  Loses outer 'iTitle's.
--- Yields empty inputs when not a (possibly titled) pair-style input.
-asIPair :: Input (~>) (a,b) -> (Input (~>) a, Input (~>) b)
-asIPair (IPair  a b ) = (a,b)
-asIPair (ITitle _ ab) = asIPair ab
-asIPair i             = error ("asIPair of non-IPair "++show i)
--- asIPair _             = (iEmpty, iEmpty)
+input :: (Pair src, Title_f src) => Input src t -> src t
 
--- Alternatively, transform titles
--- asIPair (ITitle s ab) = ( ITitle ("first of " ++s) a
---                         , ITitle ("second of "++s) b )
---  where
---    (a,b) = asIPair ab
+input (IPrim ft)     = ft
+input (IPair a b)    = input a `pair` input b
+input (ITitle str t) = title_f str (input t)
 
 
 {----------------------------------------------------------
@@ -81,37 +71,48 @@
 -- The rest just rename the constructors.  Maybe eliminate.
 -- Keep for now, since Haddock can't digest the constructor declarations.
 
-{-
--- | An empty (invisible) input for when we don't know what else to do.
--- Careful: this one probably yields bottom when used.
-iEmpty :: Input (~>) a
-iEmpty = IEmpty
--}
-
 -- Alternatively, eliminate IEmpty and define
 
--- iEmpty = iPrim $ (~>) $ const $ error "cannot get value from empty input"
-
 -- | Input primitive
-iPrim :: () ~> a -> Input (~>) a
+iPrim :: src a -> Input src a
 iPrim = IPrim
 
 -- | Input a pair
-iPair :: Input (~>) a -> Input (~>) b -> Input (~>) (a,b)
+iPair :: Input src a -> Input src b -> Input src (a,b)
 iPair = IPair
 
+instance Pair (Input src) where pair = iPair
+
 -- | Massage via an arrow value (generalizes fmap)
-iCompose :: Arrow (~>) => Input (~>) a -> a ~> b -> Input (~>) b
-IPrim put `iCompose` arr = IPrim (put >>> arr)
-i         `iCompose` _   = error ("iCompose given non-IPrim: "++show i)
+fmapO :: Functor src => (a -> b) -> Input src a -> Input src b
+fmapO f (IPrim fa)     = IPrim (fmap f fa)
+fmapO f (ITitle str a) = ITitle str (fmapO f a)
+fmapO _ i              = error ("fmap given non-IPrim: "++show i)
 
--- iCompose = ICompose
+-- Not sure about the ITitle choice.  Maybe mention fmap.
 
+instance Functor src => Functor (Input src) where fmap = fmapO
+
 -- | Title (label) an input
-iTitle :: String -> Input (~>) a -> Input (~>) a
+iTitle :: String -> Input src a -> Input src a
 iTitle = ITitle
 
 
--- | Handy specialization of 'iCompose'
-instance Arrow (~>) => Functor (Input (~>)) where
-  fmap f input = input `iCompose` pure f
+
+{----------------------------------------------------------
+    Canonicalizers
+----------------------------------------------------------}
+
+-- | Dissect a pair-valued input into two inputs.  Loses outer 'iTitle's.
+-- Must be a (possibly titled) pair-style input.
+asIPair :: Input src (a,b) -> (Input src a, Input src b)
+asIPair (IPair  a b ) = (a,b)
+asIPair (ITitle _ ab) = asIPair ab
+asIPair i             = error ("asIPair of non-IPair "++show i)
+-- asIPair _             = (iEmpty, iEmpty)
+
+-- Alternatively, transform titles
+-- asIPair (ITitle s ab) = ( ITitle ("first of " ++s) a
+--                         , ITitle ("second of "++s) b )
+--  where
+--    (a,b) = asIPair ab
diff --git a/src/Interface/TV/Misc.hs b/src/Interface/TV/Misc.hs
--- a/src/Interface/TV/Misc.hs
+++ b/src/Interface/TV/Misc.hs
@@ -13,30 +13,31 @@
 -- Miscellaneous helpers
 ----------------------------------------------------------------------
 
+
 module Interface.TV.Misc
   (
-   readD, Cofunctor(..), ToIO(..), wrapF
+   -- readD {-, Cofunctor(..), ToIO(..), wrapF -}
   ) where
 
-import Control.Arrow (Arrow)
-
 -- | Read with default value.  If the input doesn't parse as a value of
 -- the expected type, or it's ambiguous, yield the default value.
 readD :: Read a => a -> String -> a
 readD dflt str | [(a,"")] <- reads str = a
                | otherwise             = dflt
 
--- | Often useful for \"acceptors\" of values.
-class Cofunctor acceptor where
-  cofmap :: (a -> b) -> (acceptor b -> acceptor a)
+-- Cofunctor is in TypeCompose
 
--- | Arrows that convert to IO actions.
-class Arrow (~>) => ToIO (~>) where
-  -- Result type is restricted to () to allow arr types that yield more
-  -- (or fewer) than one value.
-  toIO :: () ~> () -> IO ()
+-- -- | Often useful for \"acceptors\" of values.
+-- class Cofunctor acceptor where
+--   cofmap :: (a -> b) -> (acceptor b -> acceptor a)
 
+-- -- | Arrows that convert to IO actions.
+-- class Arrow (~>) => ToIO (~>) where
+--   -- Result type is restricted to () to allow arr types that yield more
+--   -- (or fewer) than one value.
+--   toIO :: () ~> () -> IO ()
+
 -- | Handy wrapping pattern.  For instance, @wrapF show read@ turns a
 -- string function into value function.
-wrapF :: (c->d) -> (a->b) -> ((b->c) -> (a->d))
-wrapF after before f = after . f . before
+-- wrapF :: (c->d) -> (a->b) -> ((b->c) -> (a->d))
+-- wrapF after before f = after . f . before
diff --git a/src/Interface/TV/OFun.hs b/src/Interface/TV/OFun.hs
--- a/src/Interface/TV/OFun.hs
+++ b/src/Interface/TV/OFun.hs
@@ -1,56 +1,61 @@
-{-# OPTIONS -fglasgow-exts #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+-- For ghc 6.6 compatibility
+-- {-# OPTIONS -fglasgow-exts #-}
 
 ----------------------------------------------------------------------
 -- |
 -- Module      :  Interface.TV.OFun
 -- Copyright   :  (c) Conal Elliott 2006
--- License     :  LGPL
+-- License     :  BSD3
 -- 
 -- Maintainer  :  conal@conal.net
 -- Stability   :  experimental
--- Portability :  portable
+-- Portability :  MultiParamTypeClasses
 -- 
 -- 'Output' transformations, as a deep arrow.
 ----------------------------------------------------------------------
 
-module Interface.TV.OFun (OX,OFun,wrapO,wrapAO) where
+module Interface.TV.OFun (OX,OFun, wrapO{-,wrapAO-}) where
 
 import Control.Arrow
 
+import Control.Compose (Cofunctor(..))
+
 import Data.FunArr
 import Control.Arrow.DeepArrow
 
 import Interface.TV.Output
 import Interface.TV.Input
+-- import Interface.TV.Misc
 
 -- | Output functions.
-type OX (~>) a b = Output (~>) a -> Output (~>) b
+type OX dom ran a b = Output dom ran a -> Output dom ran b
 
 -- | Output functions as a 'DeepArrow'
-newtype OFun (~>) a b = OFun (OX (~>) a b)
+newtype OFun dom ran a b = OFun (OX dom ran a b)
 
 -- TODO: consider generalizing from "->" in IFun?
 
-instance Arrow (OFun (~>)) where
-  -- (a->b) -> OFun (~>) a b
+instance Arrow (OFun dom ran) where
+  -- (a->b) -> OFun dom ran a b
   arr = error "Interface.TV.OFun: no 'arr' method"
         -- We could use the following definition instead.
         -- const $ OFun (const OEmpty)
 
-  -- OFun (~>) a b -> OFun (~>) b c -> OFun (~>) a c
+  -- OFun dom ran a b -> OFun dom ran b c -> OFun dom ran a c
   OFun f >>> OFun g = OFun (f >>> g)
 
-  -- OFun (~>) a a' -> OFun (~>) (a,b) (a',b)
+  -- OFun dom ran a a' -> OFun dom ran (a,b) (a',b)
   first (OFun f) = OFun (firstO f)
 
-  -- OFun (~>) b b' -> OFun (~>) (a,b) (a,b')
+  -- OFun dom ran b b' -> OFun dom ran (a,b) (a,b')
   second (OFun f) = OFun (secondO f)
   -- Or, as recommended in DeepArrow.
   -- second f = swapA >>> first f >>> swapA
   -- As recommended
   f &&& g = dupA >>> f *** g
 
-instance DeepArrow (OFun (~>)) where
+instance DeepArrow (OFun dom ran) where
   idA      = OFun id
   dupA     = postFun "dup" dupO
   fstA     = postFun "first half" fstO
@@ -65,24 +70,24 @@
   result   (OFun ox) = OFun (resultO   ox)
   -- argument (OFun ox) = OFun (argumentO ox)
 
-instance FunArr (OFun (~>)) (Output (~>)) where
+instance FunArr (OFun dom ran) (Output dom ran) where
   toArr ofun = OFun (applyO ofun)
   OFun ox $$ o = ox o
 
 -- Alter any outer titles before transforming
-retitle :: (String -> String) -> OX (~>) a b -> OX (~>) a b
+retitle :: (String -> String) -> OX dom ran a b -> OX dom ran a b
 retitle re ofun (OTitle str o) = OTitle (re str) (retitle re ofun o)
 retitle _  ofun o = ofun o
 
 -- Alter by appending a comment
-posttitle :: String -> OX (~>) a b -> OX (~>) a b
+posttitle :: String -> OX dom ran a b -> OX dom ran a b
 posttitle post = retitle (++ (" -- " ++ post))
 
 -- Convenient wrappers
--- reFun :: (String->String) -> OX (~>) a b -> OFun (~>) a b
+-- reFun :: (String->String) -> OX dom ran a b -> OFun dom ran a b
 -- reFun re = OFun . retitle re
 
-postFun :: String -> OX (~>) a b -> OFun (~>) a b
+postFun :: String -> OX dom ran a b -> OFun dom ran a b
 postFun post = OFun . posttitle post
 
 -- Why don't we do postFun for 'result'?  Because we get funny titles when
@@ -92,82 +97,77 @@
 
 ---- Output transformers
 
-resultO :: OX (~>) b b' -> OX (~>) (a->b) (a->b')
+resultO :: OX dom ran b b' -> OX dom ran (a->b) (a->b')
 resultO ox ab = OLambda a (ox b)
   where (a,b) = asOLambda ab
 
--- argumentO :: OX (~>) a' a -> OX (~>) (a->b) (a'->b)
+-- argumentO :: OX dom ran a' a -> OX dom ran (a->b) (a'->b)
 -- argumentO ox ab = 
 
-applyO :: Output (~>) (a->b) -> OX (~>) a b
+applyO :: Output dom ran (a->b) -> OX dom ran a b
 applyO o = const b where (_,b) = asOLambda o
 
-firstO :: OX (~>) a c -> OX (~>) (a,b) (c,b)
+firstO :: OX dom ran a c -> OX dom ran (a,b) (c,b)
 firstO f ab = OPair (f a) b where (a,b) = asOPair ab
 
-secondO :: OX (~>) b c -> OX (~>) (a,b) (a,c)
+secondO :: OX dom ran b c -> OX dom ran (a,b) (a,c)
 secondO f ab = OPair a (f b) where (a,b) = asOPair ab
 
-dupO :: OX (~>) a (a,a)
+dupO :: OX dom ran a (a,a)
 dupO a = OPair a a
 
-fstO :: OX (~>) (a,b) a
+fstO :: OX dom ran (a,b) a
 fstO ab = a where (a,_) = asOPair ab
 
-sndO :: OX (~>) (a,b) b
+sndO :: OX dom ran (a,b) b
 sndO ab = b where (_,b) = asOPair ab
 
-funFO :: OX (~>) (c->a,b) (c->(a,b))
+funFO :: OX dom ran (c->a,b) (c->(a,b))
 funFO gb = OLambda c (OPair a b)
   where
     (g,b) = asOPair gb
     (c,a) = asOLambda g
 
 -- Try this style
--- funFO' :: OX (~>) (c->a,b) (c->(a,b))
+-- funFO' :: OX dom ran (c->a,b) (c->(a,b))
 -- funFO' gb = OLambda c (OPair a b)
 --   where
 --     ((c,a),b) = first asOLambda (asOPair gb)
 
-funSO :: OX (~>) (a,c->b) (c->(a,b))
+funSO :: OX dom ran (a,c->b) (c->(a,b))
 funSO ag = OLambda c (OPair a b)
   where
     (a,g) = asOPair ag
     (c,b) = asOLambda g
 
-funRO :: OX (~>) (a->b->c) (b->a->c)
+funRO :: OX dom ran (a->b->c) (b->a->c)
 funRO abc = OLambda b (OLambda a c) 
  where
    (a,bc) = asOLambda abc
    (b,c)  = asOLambda bc
 
-swapO :: OX (~>) (a,b) (b,a)
+swapO :: OX dom ran (a,b) (b,a)
 swapO ab = OPair b a where (a,b) = asOPair ab
 
-curryO :: OX (~>) ((a,b)->c) (a->b->c)
+curryO :: OX dom ran ((a,b)->c) (a->b->c)
 curryO o = OLambda a (OLambda b c)
   where (ab,c) = asOLambda o
         (a ,b) = asIPair ab
 
-uncurryO :: OX (~>) (a->b->c) ((a,b)->c)
+uncurryO :: OX dom ran (a->b->c) ((a,b)->c)
 uncurryO o = OLambda (IPair a b) c
   where (a,bc) = asOLambda o
         (b, c) = asOLambda bc
 
 -- For now leave lAssocA and rAssocA as default.
 
-
 ---- Other functions
 
 -- | Like @wrapF@, but for outputs and reversed orientation.
 -- Specialization of 'wrapAO'.
-wrapO :: Arrow (~>) => (b'->b) -> (a->a') -> OX (~>) (a->b) (a'->b')
-wrapO g f = wrapAO (pure g) (pure f)
-
--- | Generalizes 'wrapO' for arbitrary arrows.
-wrapAO :: Arrow (~>) =>
-          (b' ~> b) -> (a ~> a') -> OX (~>) (a->b) (a'->b')
-wrapAO outer inner ab = OLambda (ia `iCompose` inner) (outer `oCompose` ob)
+wrapO :: (Functor dom, Cofunctor ran) =>
+         (b'->b) -> (a->a') -> OX dom ran (a->b) (a'->b')
+wrapO outer inner ab = OLambda (fmap inner ia) (cofmap outer ob)
  where
    (ia,ob) = asOLambda ab
 
@@ -175,5 +175,3 @@
 -- Then we get an elegant definition of @interactRSOut@:
 
 -- interactRSOut dflt = wrapO show (readD dflt) interactLine
-
-
diff --git a/src/Interface/TV/Output.hs b/src/Interface/TV/Output.hs
--- a/src/Interface/TV/Output.hs
+++ b/src/Interface/TV/Output.hs
@@ -1,14 +1,16 @@
-{-# OPTIONS -fglasgow-exts -cpp #-}
+{-# LANGUAGE GADTs, KindSignatures, MultiParamTypeClasses #-}
+-- For ghc 6.6 compatibility
+-- {-# OPTIONS -fglasgow-exts #-}
 
 ----------------------------------------------------------------------
 -- |
 -- Module      :  Interface.TV.Output
 -- Copyright   :  (c) Conal Elliott 2006
--- License     :  LGPL
+-- License     :  BSD3
 -- 
 -- Maintainer  :  conal@conal.net
 -- Stability   :  experimental
--- Portability :  portable
+-- Portability :  GADTs
 -- 
 -- Outputs (interfaces) -- means of presenting values
 ----------------------------------------------------------------------
@@ -16,47 +18,48 @@
 module Interface.TV.Output
   (
   -- * Output data type
-    Output(..)
+    Output(..), output
   -- * Output functions
-  -- ** General
-  {-, oEmpty-}, oPrim, oLambda, oPair, oCompose, oTitle
+  -- ** Builders
+  , oPrim, oLambda, oPair, oTitle
   -- ** Canonicalizers
   , asOLambda, asOPair
+--   -- ** Type specialization
+--   , Output', oPrim'
   ) where
 
-import Control.Arrow
 
+import Control.Compose (Cofunctor(..))
+import Data.Pair (Pair(..))
+import Data.Lambda (Lambda(..))
+import Data.Title (Title_f(..))
+
+
 import Interface.TV.Input
-import Interface.TV.Misc (Cofunctor(..))
 
 
+
 {----------------------------------------------------------
     Output data type
 ----------------------------------------------------------}
 
 -- | An /Output/ describes a way to present a functional value, perhaps
 -- interactively.  It is the user-interface half of a tangible value.
-#ifdef __HADDOCK__
-data Output (~>) a
-#else
-data Output (~>) :: * -> * where
-  -- | When we don't know what output to use.  I might remove this constructor.
-  -- OEmpty :: Output (~>) a
+data Output src snk :: * -> * where
   -- | Output primitive
-  OPrim :: a ~> () -> Output (~>) a
+  OPrim :: snk a -> Output src snk a
   -- | Visualize a function.  Akin to /lambda/
-  OLambda :: Input (~>)  a -> Output (~>) b -> Output (~>) (a->b)
+  OLambda :: Input src  a -> Output src snk b -> Output src snk (a->b)
   -- | Visualize a pair
-  OPair :: Output (~>) a -> Output (~>) b -> Output (~>) (a,b)
+  OPair :: Output src snk a -> Output src snk b -> Output src snk (a,b)
   -- | Massage via an arrow value (like cofmap)
-  -- OCompose :: a ~> b -> Output (~>) b -> Output (~>) a
+  -- OCompose :: src (a -> b) -> Output src snk b -> Output src snk a
   -- | Title/label an output
-  OTitle :: String -> Output (~>) a -> Output (~>) a
-#endif
+  OTitle :: String -> Output src snk a -> Output src snk a
 
--- See 'OEmpty' for note about eliminating OEmpty.
+instance Title_f (Output src snk) where title_f = OTitle
 
-instance Show (Output (~>) a) where
+instance Show (Output src snk a) where
   -- show OEmpty          = "OEmpty"
   show (OPrim _)       = "(OPrim _)"
   show (OLambda i o)   = "(Lambda "++show i++" "++show o++")"
@@ -65,13 +68,24 @@
   show (OTitle str o)  = "(OTitle "++show str++" "++show o++")"
 
 
+output :: (Pair src, Pair snk, Lambda src snk, Title_f src, Title_f snk) =>
+          Output src snk t -> snk t
+
+output (OPrim rant)   = rant
+output (OPair   a b)  = pair   (output a) (output b)
+output (OLambda i o)  = lambda (input  i) (output o)
+output (OTitle str t) = title_f str (output t)
+
+
+
+
 {----------------------------------------------------------
     Canonicalizers
 ----------------------------------------------------------}
 
 -- | Dissect a pair-valued input into two inputs.  Loses outer 'oTitle's.
--- Yields empty inputs when not a (possibly titled) pair-style input.
-asOLambda :: Output (~>) (a->b) -> (Input (~>) a, Output (~>) b)
+-- Must be a (possibly titled) pair-style input.
+asOLambda :: Output src snk (a->b) -> (Input src a, Output src snk b)
 asOLambda (OLambda a b) = (a,b)
 asOLambda (OTitle _ ab) = asOLambda ab
 asOLambda o             = error ("asOLambda of non-OLambda "++show o)
@@ -85,7 +99,7 @@
 --  where
 --    (a,b) = asOLambda ab
 
-asOPair :: Output (~>) (a,b) -> (Output (~>) a, Output (~>) b)
+asOPair :: Output src snk (a,b) -> (Output src snk a, Output src snk b)
 asOPair (OPair  a b ) = (a,b)
 asOPair (OTitle _ ab) = asOPair ab
 asOPair o             = error ("asOPair of non-OPair "++show o)
@@ -107,40 +121,37 @@
 -- These functions just rename the constructors.  Maybe eliminate.
 -- Keep for now, since Haddock can't digest the constructor declarations.
 
-{-
--- | An empty (invisible) output for when we don't know what else to do.
-oEmpty :: Output (~>) a
-oEmpty = OEmpty
--}
-
--- Alternatively, eliminate OEmpty and define
-
--- oEmpty = oPrim (arr $ const ())
-
-
 -- | Output primitive
-oPrim :: a ~> () -> Output (~>) a
+oPrim :: snk a -> Output src snk a
 oPrim = OPrim
 
 -- | Visualize a function.  Akin to /lambda/
-oLambda :: Input (~>)  a -> Output (~>) b -> Output (~>) (a->b)
+oLambda :: Input src  a -> Output src snk b -> Output src snk (a->b)
 oLambda = OLambda
 
 -- | Visualize a pair
-oPair :: Output (~>) a -> Output (~>) b -> Output (~>) (a,b)
+oPair :: Output src snk a -> Output src snk b -> Output src snk (a,b)
 oPair = OPair
 
--- | Massage via an arrow value (like cofmap)
-oCompose :: Arrow (~>) => a ~> b -> Output (~>) b -> Output (~>) a
-arr `oCompose` OPrim put = OPrim (arr >>> put)
-_   `oCompose` o         = error ("oCompose given non-OPrim: "++show o)
 
--- oCompose = OCompose
+instance Pair (Output src snk) where pair = oPair
 
+instance Lambda (Input src) (Output src snk) where lambda = oLambda
+
+
 -- | Title (label) an output
-oTitle :: String -> Output (~>) a -> Output (~>) a
+oTitle :: String -> Output src snk a -> Output src snk a
 oTitle = OTitle
 
--- | Handy specialization of 'oCompose'
-instance Arrow (~>) => Cofunctor (Output (~>)) where
-  cofmap f input = pure f `oCompose` input
+
+-- I specialized oCompose to cofmapO.  I don't think there's enough
+-- machinery to do oCompose.
+
+cofmapO :: Cofunctor snk => (a -> b) -> Output src snk b -> Output src snk a
+f `cofmapO` OPrim ranb    = OPrim (cofmap f ranb)
+f `cofmapO` OTitle str ab = OTitle str (f `cofmapO` ab)
+_ `cofmapO` o             = error ("cofmapO given non-OPrim: "++show o)
+
+instance Cofunctor snk => Cofunctor (Output src snk) where
+  cofmap = cofmapO
+
diff --git a/src/Interface/TV/Present.hs b/src/Interface/TV/Present.hs
--- a/src/Interface/TV/Present.hs
+++ b/src/Interface/TV/Present.hs
@@ -15,7 +15,7 @@
 
 module Interface.TV.Present
   (
-   present, Present(..)
+   present, accept, Present(..)
   ) where
 
 import Control.Arrow
diff --git a/src/Interface/TV/Tangible.hs b/src/Interface/TV/Tangible.hs
--- a/src/Interface/TV/Tangible.hs
+++ b/src/Interface/TV/Tangible.hs
@@ -1,14 +1,16 @@
-{-# OPTIONS -fglasgow-exts #-}
+{-# LANGUAGE Rank2Types, TypeOperators #-}
+-- For ghc 6.6 compatibility
+-- {-# OPTIONS -fglasgow-exts #-}
 
 ----------------------------------------------------------------------
 -- |
 -- Module      :  Interface.TV.Tangible
 -- Copyright   :  (c) Conal Elliott 2006
--- License     :  LGPL
+-- License     :  BSD3
 -- 
 -- Maintainer  :  conal@conal.net
 -- Stability   :  experimental
--- Portability :  portable
+-- Portability :  Rank2Types
 -- 
 -- Tangible values -- interface (output) and value, combined & separable
 ----------------------------------------------------------------------
@@ -16,45 +18,52 @@
 module Interface.TV.Tangible
   (
   -- * Tangible values
-   TV, tv, unTv, RunTV, runTV
+   TV, TVFun, tv, unTv, RunTV, runTV
   ) where
 
-import Control.Arrow
-import Control.Monad.Identity
+import Control.Compose (Id(..),(:*:)(..),(::*::)(..),Flip(..),ToOI(..))
+import Data.Pair
+import Data.Lambda
+import Data.Title
 
-import Data.Tupler
+-- import Data.Tupler
 import Interface.TV.Output
-import Interface.TV.Present
-import Interface.TV.Misc
+import Interface.TV.OFun
 
 -- import Control.Arrow.DeepArrow
 -- import Data.FunArr
 -- import Interface.TV.OFun 
 
 -- | Tangible values (TVs).
-type TV (~>) a = Pair1 (Output (~>)) Identity a
+type TV src snk = Output src snk :*: Id
 
+-- | Arrow on 'TV's
+type TVFun src snk = OFun src snk ::*:: (->)
+
+
 -- To do: use a newtype for TV, for friendlier messages.  Requires TVFun
 -- and FunArr instance below.  Unfortunately, GHC will not automatically
 -- derive the instances I'll need.
 
 -- -- | 'DeepArrow' corresponding to 'TV'
--- newtype TVFun (~>) a b = TVFun (Pair2 (OFun (~>)) (->) a b) deriving DeepArrow
+-- newtype TVFun src snk a b = TVFun (Pair2 (OFun src snk) (->) a b) deriving DeepArrow
 
--- instance FunArr (~>) => FunArr (TVFun (~>)) (TV (~>))
+-- instance FunArr src snk => FunArr (TVFun src snk) (TV src snk)
 
 -- | Make a 'TV'
-tv :: Output (~>) a -> a -> TV (~>) a
-tv o a = Pair1 (o, return a)
+tv :: Output src snk a -> a -> TV src snk a
+tv o a = Prod (o, Id a)
 
 -- | Dissect a 'TV'
-unTv :: TV (~>) a -> (Output (~>) a, a)
-unTv (Pair1 (o, ida)) = (o, runIdentity ida)
+unTv :: TV src snk a -> (Output src snk a, a)
+unTv (Prod (o, ida)) = (o, unId ida)
 
 -- | Useful to define disambiguating type-specializations of 'runTV'
-type RunTV (~>) = forall a. TV (~>) a -> IO ()
+type RunTV src snk = forall a. TV src snk a -> IO ()
 
 -- | Run a 'TV'
-runTV :: (ToIO (~>), Present (~>)) => RunTV (~>)
-runTV teevee = toIO (pure (const a) >>> present o)
+runTV :: ( Title_f snk, Title_f src
+         , Lambda src snk, Pair snk, Pair src
+         , ToOI snk) => RunTV src snk
+runTV teevee = unFlip (toOI (output o)) a
   where (o,a) = unTv teevee
diff --git a/src/Interface/TV/TestAF.hs b/src/Interface/TV/TestAF.hs
new file mode 100644
--- /dev/null
+++ b/src/Interface/TV/TestAF.hs
@@ -0,0 +1,263 @@
+{-# OPTIONS -fglasgow-exts #-}
+
+----------------------------------------------------------------------
+-- |
+-- Module      :  TestAF
+-- Copyright   :  (c) Conal Elliott 2007
+-- License     :  LGPL
+-- 
+-- Maintainer  :  conal@conal.net
+-- Stability   :  experimental
+-- Portability :  GADT
+-- 
+-- Experiments in (applicative) functors for TV
+----------------------------------------------------------------------
+
+module TestAF
+  (
+  
+  ) where
+
+
+import Control.Applicative
+import Control.Monad (liftM2)
+import Data.Monoid
+import Control.Arrow hiding (pure)
+import Control.Compose
+-- import Control.Instances
+
+import qualified Interface.TV.Present as P (Present(..))
+
+-- | An /Input/ describes a way to obtain a functional value from a user.
+-- Used in Output for making function visualizations.
+data Input :: (* -> *) -> * -> * where
+  -- | Input primitive
+  IPrim :: f a -> Input f a
+  -- | Input a pair
+  IPair :: Input f a -> Input f b -> Input f (a,b)
+  -- | Title/label an input
+  ITitle :: String -> Input f a -> Input f a
+
+-- | An /Output/ describes a way to present a functional value, perhaps
+-- interactively.  It is the interface half of a tangible value.
+data Output :: (* -> *) -> * -> * -> * where
+  -- | Output primitive
+  OPrim :: f (a -> o) -> Output f o a
+  -- | Visualize a function.  Akin to /lambda/
+  OLambda :: Input f a -> Output f o b -> Output f o (a->b)
+  -- | Visualize a pair
+  OPair :: Output f o a -> Output f o b -> Output f o (a,b)
+  -- | Title/label an output
+  OTitle :: String -> Output f o a -> Output f o a
+
+
+
+ipairA :: Applicative f => f a -> f b -> f (a,b)
+ipairA = liftA2 (,)
+
+olambdaA :: Applicative f => f a -> f (b -> o) -> f ((a->b) -> o)
+olambdaA = liftA2 (\ a snkb -> \ f -> snkb (f a))
+
+opairA :: (Applicative f, Monoid o) =>
+  f (a -> o) -> f (b -> o) -> f ((a,b) -> o)
+opairA = liftA2 sinkPair
+ where
+   sinkPair :: Monoid o => (a -> o) -> (b -> o) -> ((a,b) -> o)
+   sinkPair ka kb = \ (a,b) -> ka a `mappend` kb b
+
+-- | 'present' requires a bit of arrow-specific help.  For instance, in
+-- UIs, pairs are presented horizontally, lambdas vertically, and titles
+-- with a labeled box.  I'm not really comfortable with this part of the
+-- design, especially the specificity of addressing titles here.  All of
+-- the methods here have do-nothing defaults, so you can simply say
+-- @instance Present arr@ for your arrow @arr@.
+class Present f where
+  presentPair     :: f a -> f a
+  presentPair     =  id
+  presentLambda   :: f a -> f a
+  presentLambda   =  id
+  presentTitle    :: String -> f a -> f a
+  presentTitle _  =  id
+
+-- | Convert an 'Input' into an arrow value.
+accept :: (Applicative f, Present f) => Input f b -> f b
+
+accept (IPrim p)       = p
+accept (IPair ia ib)   = presentPair $ ipairA (accept ia) (accept ib)
+accept (ITitle str i)  = presentTitle str $ accept i
+
+
+-- | Convert an 'Output' into an arrow value
+present :: (Applicative f, Monoid o, Present f) => Output f o a -> f (a -> o)
+
+present (OPrim p)       = p
+present (OPair oa ob)   = presentPair $ opairA (present oa) (present ob)
+present (OLambda i o)   = presentLambda $ olambdaA (accept i) (present o)
+present (OTitle str o)  = presentTitle str $ present o
+
+
+---- Next, generalize from the particular style of consumer (@f (a -> o)@)
+
+class Pair cof where
+  pair :: cof a -> cof b -> cof (a,b)
+
+class Lambda f cof where
+  lambda :: f a -> cof b -> cof (a->b)
+
+-- class Cof f cof | cof -> f where
+--   lambda  ::   f a -> cof b -> cof (a->b)
+--   pair :: cof a -> cof b -> cof (a, b)
+
+
+---- Monads
+
+olambdaM :: Monad m => m a -> (b -> m o) -> ((a->b) -> m o)
+olambdaM ioa oib = \ f -> ioa >>= oib . f
+
+opairM :: (Monad m, Monoid o) =>
+  (a -> m o) -> (b -> m o) -> ((a,b) -> m o)
+opairM coa cob = \ (a,b) -> liftM2 mappend (coa a) (cob b)
+
+-- Repackage 'olambdaA', 'opairA' for use in a 'Lambda' instance.
+
+type CoM m o = Flip (->) (m o)
+
+lamM :: Monad m => m a -> CoM m o b -> CoM m o (a->b)
+lamM ioa = inFlip (olambdaM ioa)
+
+pairM :: (Monad m, Monoid o) =>
+  CoM m o a -> CoM m o b -> CoM m o (a,b)
+pairM = inFlip2 opairM
+
+instance Present f => Present (CoM f o) where
+  presentPair      = inFlip (presentPair .)
+  presentLambda    = inFlip (presentLambda .)
+  presentTitle str = inFlip (presentTitle str .)
+
+-- Standard instance: replace IO with any monad
+instance Monoid o => Pair (CoM IO o) where
+  pair = pairM
+instance Lambda IO (CoM IO o) where
+  lambda = lamM
+
+-- instance Monoid o => Cof IO (CoM IO o) where
+--   lambda  = lamM
+--   pair = pairM
+
+
+---- Applicative functors
+
+-- Repackage 'olambdaA', 'opairA' for use in a 'Lambda' instance.
+
+type CoA f o = O f (Flip (->) o)
+
+coA :: Functor f => f (b -> o) -> CoA f o b
+coA = O . fmap Flip
+
+unCoA :: Functor f => CoA f o b -> f (b -> o)
+unCoA = fmap unFlip . unO
+
+inCoA :: (Functor f, Functor g)
+  => (f (a -> o) -> g (b -> p))
+  -> (CoA f o a  -> CoA g p b)
+inCoA f = coA . f . unCoA
+
+inCoA2 :: (Functor f, Functor g, Functor h)
+  => (f (a -> o) -> g (b -> p) -> h (c -> q))
+  -> (CoA f o a  -> CoA g p b  -> CoA h q c)
+inCoA2 f coa coa' = coA (f (unCoA coa) (unCoA coa'))
+
+--   or
+-- inCoA2 f coa = inCoA (f (unCoA coa))
+
+
+lamA :: Applicative f => f a -> CoA f o b -> CoA f o (a->b)
+lamA fa = inCoA (olambdaA fa)
+
+pairA :: (Applicative f, Monoid o) =>
+  CoA f o a -> CoA f o b -> CoA f o (a,b)
+pairA = inCoA2 opairA
+
+
+instance (Functor f, Present f) => Present (CoA f o) where
+  presentPair      = inCoA presentPair
+  presentLambda    = inCoA presentLambda
+  presentTitle str = inCoA (presentTitle str)
+
+-- Standard instance: replace [] with any AF, particularly non-monads.
+instance Monoid o => Pair (CoA [] o) where
+  pair = pairA
+instance Lambda [] (CoA [] o) where
+  lambda  = lamA
+
+-- instance Monoid o => Cof [] (CoA [] o) where
+--   lambda  = lamA
+--   pair = pairA
+
+
+---- Arrows
+
+olambdaAr :: (Monoid i, Arrow (~>)) => (i ~> a) -> (b ~> o) -> ((a->b) ~> o)
+olambdaAr ia ob = 
+  arr (\ f -> (f, mempty))  >>>
+  second ia                 >>>
+  arr (uncurry ($))         >>>
+  ob
+
+opairAr :: (Arrow (~>), Monoid o) => (a ~> o) -> (b ~> o) -> ((a,b) ~> o)
+opairAr oa ob = (oa *** ob) >>> arr (uncurry mappend)
+
+
+-- Repackage 'olambdaAr', 'opairAr' for use in a 'Lambda' instance.
+
+lamAr :: (Monoid i, Arrow (~>)) => (i ~> a) -> Flip (~>) o b -> Flip (~>) o (a->b)
+lamAr ia = inFlip (olambdaAr ia)
+
+pairAr :: (Monoid o, Arrow (~>)) =>
+  Flip (~>) o a -> Flip (~>) o b -> Flip (~>) o (a,b)
+pairAr = inFlip2 opairAr
+
+
+instance P.Present (~>) => Present (Flip (~>) o) where
+  presentPair      = inFlip P.presentPair
+  presentLambda    = inFlip P.presentLambda
+  presentTitle str = inFlip (P.presentTitle str)
+
+
+-- Standard instances: replace (->) with any arrow and () and [a] with any monoid
+instance Pair (Flip (->) [a]) where
+  pair = pairAr
+instance Lambda ((->) ()) (Flip (->) [a]) where
+  lambda  = lamAr
+
+-- instance Cof ((->) ()) (Flip (->) [a]) where
+--   lambda  = lamAr
+--   pair = pairAr
+
+
+-- The type packaging used in CoM & CoA (Flip and O) complicate the
+-- definitions.  Maybe type-indexed synonyms (not yet implemented) will
+-- eliminate them.
+
+
+
+-- | Alternative to 'Output'
+data Output' :: (* -> *) -> (* -> *) -> (* -> *) where
+  -- | Output primitive
+  OPrim' :: cof a -> Output' f cof a
+  -- | Visualize a function.  Akin to /lambda/
+  OLambda' :: Input f a -> Output' f cof b -> Output' f cof (a->b)
+  -- | Visualize a pair
+  OPair' :: Output' f cof a -> Output' f cof b -> Output' f cof (a,b)
+  -- | Title/label an output
+  OTitle' :: String -> Output' f cof a -> Output' f cof a
+
+-- | Convert an 'Output' into an arrow value
+present' :: (Applicative f, Pair cof, Lambda f cof, Present f, Present cof) =>
+  Output' f cof a -> cof a
+
+present' (OPrim' p)       = p
+present' (OPair' oa ob)   = presentPair $ pair (present' oa) (present' ob)
+present' (OLambda' i o)   = presentLambda $ lambda (accept i) (present' o)
+present' (OTitle' str o)  = presentTitle str $ present' o
+
diff --git a/src/Interface/TV/UI.hs b/src/Interface/TV/UI.hs
--- a/src/Interface/TV/UI.hs
+++ b/src/Interface/TV/UI.hs
@@ -31,7 +31,7 @@
 import Interface.TV.Present (Present(..))
 import Interface.TV.Common (CommonInsOuts(..))
 import Interface.TV.Tangible (RunTV,runTV)
-import Interface.TV.Misc (ToIO(..))
+-- import Interface.TV.Misc (ToIO(..))
 
 
 {----------------------------------------------------------
