Skip to content

Commit

Permalink
Converted to experimental TypeFamily-based isos and projections
Browse files Browse the repository at this point in the history
  • Loading branch information
ekmett committed Dec 1, 2012
1 parent d42e4c1 commit 8a9110e
Show file tree
Hide file tree
Showing 21 changed files with 84 additions and 33 deletions.
7 changes: 7 additions & 0 deletions lens.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -143,11 +143,16 @@ flag test-hunit
default: True
manual: True

flag test-properties
default: True
manual: True

-- Disallow unsafeCoerce
flag safe
default: False
manual: True


library
build-depends:
base >= 4.4 && < 5,
Expand Down Expand Up @@ -277,6 +282,8 @@ test-suite properties
transformers
ghc-options: -w -threaded
hs-source-dirs: tests
if !flag(test-properties)
buildable: False

test-suite hunit
type: exitcode-stdio-1.0
Expand Down
1 change: 1 addition & 0 deletions src/Control/Exception/Lens.hs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE ScopedTypeVariables #-}
-----------------------------------------------------------------------------
Expand Down
32 changes: 26 additions & 6 deletions src/Control/Lens/Classes.hs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ module Control.Lens.Classes
, Projective(..)
-- * Indexable
, Indexable(..)
-- * Families
, CoalgebraicA
, CoalgebraicB
, CoalgebraicF
) where

import Control.Applicative
Expand Down Expand Up @@ -139,11 +143,23 @@ instance (Settable f, Settable g) => Settable (Compose f g) where
-- Isomorphisms
-----------------------------------------------------------------------------

type family CoalgebraicA (x :: *) :: *
type family CoalgebraicB (x :: *) :: *
type family CoalgebraicF (x :: *) :: * -> *

type instance CoalgebraicA (a -> f_b) = a
type instance CoalgebraicB (a -> f b) = b
type instance CoalgebraicF (a -> f b) = f

-- | Used to provide overloading of isomorphism application
--
-- An instance of 'Isomorphic' is a 'Category' with a canonical mapping to it from the
-- category of isomorphisms over Haskell types.
class Isomorphic r s t a b | r -> s t a b, s b -> t a, t a -> s b where
class Isomorphic r where
type S (r :: *) :: *
type T (r :: *) :: *
type A (r :: *) :: *
type B (r :: *) :: *
-- | Build a simple isomorphism from a pair of inverse functions
--
-- @
Expand All @@ -152,9 +168,13 @@ class Isomorphic r s t a b | r -> s t a b, s b -> t a, t a -> s b where
-- 'set' ('iso' f g) h ≡ g '.' h '.' f
-- 'set' ('from' ('iso' f g)) h ≡ f '.' h '.' g
-- @
iso :: (s -> a) -> (b -> t) -> r
iso :: (S r -> A r) -> (B r -> T r) -> r

instance (Functor f, x ~ (a -> f b), y ~ (s -> f t)) => Isomorphic (x -> y) s t a b where
instance (Functor f, x ~ (a -> f b), y ~ (s -> f t)) => Isomorphic (x -> y) where
type S (x -> y) = CoalgebraicA y
type T (x -> y) = CoalgebraicB y
type A (x -> y) = CoalgebraicA x
type B (x -> y) = CoalgebraicB x
iso sa bt afb s = bt <$> afb (sa s)

-----------------------------------------------------------------------------
Expand All @@ -165,13 +185,13 @@ instance (Functor f, x ~ (a -> f b), y ~ (s -> f t)) => Isomorphic (x -> y) s t
--
-- An instance of 'Projective' is a 'Category' with a canonical mapping to it from the category
-- of embedding-projection pairs over Haskell types.
class Isomorphic r s t a b => Projective r s t a b | r -> s t a b, s b -> t a, t a -> s b where
class Isomorphic r => Projective r where
-- | Build a 'Control.Lens.Projection.Projection'.
--
-- @'Either' t a@ is used instead of @'Maybe' a@ to permit the types of @s@ and @t@ to differ.
projected :: (b -> t) -> (s -> Either t a) -> r
projected :: (B r -> T r) -> (S r -> Either (T r) (A r)) -> r

instance (Applicative f, x ~ (a -> f b), y ~ (s -> f t)) => Projective (x -> y) s t a b where
instance (Applicative f, x ~ (a -> f b), y ~ (s -> f t)) => Projective (x -> y) where
projected bt seta afb = either pure (fmap bt . afb) . seta
{-# INLINE projected #-}

Expand Down
18 changes: 13 additions & 5 deletions src/Control/Lens/Internal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -493,12 +493,16 @@ instance Category Projected where
Right a -> Right a
-}

instance Projective (Projected s t a b) s t a b where
projected = Projected

instance Isomorphic (Projected s t a b) s t a b where
instance Isomorphic (Projected s t a b) where
type S (Projected s t a b) = s
type T (Projected s t a b) = t
type A (Projected s t a b) = a
type B (Projected s t a b) = b
iso sa bt = Projected bt (Right . sa)

instance Projective (Projected s t a b) where
projected = Projected

------------------------------------------------------------------------------
-- Isomorphism Internals
------------------------------------------------------------------------------
Expand All @@ -512,7 +516,11 @@ instance Category Isomorphism where
Isomorphism xs ty . Isomorphism sa bt = Isomorphism (sa.xs) (ty.bt)
-}

instance Isomorphic (Isomorphism s t a b) s t a b where
instance Isomorphic (Isomorphism s t a b) where
type S (Isomorphism s t a b) = s
type T (Isomorphism s t a b) = t
type A (Isomorphism s t a b) = a
type B (Isomorphism s t a b) = b
iso = Isomorphism

------------------------------------------------------------------------------
Expand Down
4 changes: 2 additions & 2 deletions src/Control/Lens/Iso.hs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ module Control.Lens.Iso
-- * Isomorphism Lenses
Iso
-- * Isomorphism Construction
, Isomorphic(..)
, Isomorphic(iso)
, Isomorphism(..)
-- * Consuming Isomorphisms
, from
Expand Down Expand Up @@ -109,7 +109,7 @@ cloneIso (Isomorphism sa bt) = iso sa bt
-- import Prelude hiding (('Prelude..'),'Prelude.id')
-- @
--
type Iso s t a b = forall r. Isomorphic r s t a b => r
type Iso s t a b = forall r. (Isomorphic r, S r ~ s, T r ~ t, A r ~ a, B r ~ b) => r

-- |
-- @type 'SimpleIso' = 'Control.Lens.Type.Simple' 'Iso'@
Expand Down
4 changes: 2 additions & 2 deletions src/Control/Lens/Projection.hs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ import Prelude hiding (id,(.))
-- $setup
-- >>> import Control.Lens
-- >>> import Numeric.Natural
-- >>> :set -XFlexibleContexts
-- >>> :set -XFlexibleContexts -XTypeFamilies
-- >>> let nat :: Simple Projection Integer Natural; nat = projected toInteger $ \i -> if i <= 0 then Left i else Right (fromInteger i)
-- >>> let isLeft (Left _) = True; isLeft _ = False
-- >>> let isRight (Right _) = True; isRight _ = False
Expand Down Expand Up @@ -126,7 +126,7 @@ import Prelude hiding (id,(.))
--
-- Another interesting way to think of a 'Projection' is as the categorical dual of a 'Lens'
-- a /co/-'Lens', so to speak. This is what permits the construction of 'outside'.
type Projection s t a b = forall r. Projective r s t a b => r
type Projection s t a b = forall r. (Projective r, S r ~ s, T r ~ t, A r ~ a, B r ~ b) => r

-- | A @'Simple' 'Projection'@.
type SimpleProjection s a = Projection s s a a
Expand Down
1 change: 1 addition & 0 deletions src/Control/Lens/Simple.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
-----------------------------------------------------------------------------
-- |
Expand Down
1 change: 1 addition & 0 deletions src/Control/Lens/Wrapped.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FunctionalDependencies #-}
Expand Down
5 changes: 3 additions & 2 deletions src/Data/ByteString/Lazy/Lens.hs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FlexibleContexts #-}
-----------------------------------------------------------------------------
-- |
-- Module : Data.ByteString.Lazy.Lens
-- Copyright : (C) 2012 Edward Kmett
-- License : BSD-style (see the file LICENSE)
-- Maintainer : Edward Kmett <ekmett@gmail.com>
-- Stability : provisional
-- Portability : portable
-- Stability : experimental
-- Portability : non-portable
--
-- Lenses for lazy bytestrings
----------------------------------------------------------------------------
Expand Down
5 changes: 3 additions & 2 deletions src/Data/ByteString/Lens.hs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FlexibleContexts #-}
-----------------------------------------------------------------------------
-- |
-- Module : Data.ByteString.Lens
-- Copyright : (C) 2012 Edward Kmett
-- License : BSD-style (see the file LICENSE)
-- Maintainer : Edward Kmett <ekmett@gmail.com>
-- Stability : provisional
-- Portability : portable
-- Stability : experimental
-- Portability : non-portable
--
----------------------------------------------------------------------------
module Data.ByteString.Lens
Expand Down
5 changes: 3 additions & 2 deletions src/Data/ByteString/Strict/Lens.hs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FlexibleContexts #-}
-----------------------------------------------------------------------------
-- |
-- Module : Data.ByteString.Strict.Lens
-- Copyright : (C) 2012 Edward Kmett
-- License : BSD-style (see the file LICENSE)
-- Maintainer : Edward Kmett <ekmett@gmail.com>
-- Stability : provisional
-- Portability : portable
-- Stability : experimental
-- Portability : non-portable
--
----------------------------------------------------------------------------
module Data.ByteString.Strict.Lens
Expand Down
3 changes: 2 additions & 1 deletion src/Data/Complex/Lens.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{-# LANGUAGE CPP #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FlexibleContexts #-}
#ifndef MIN_VERSION_base
#define MIN_VERSION_base(x,y,z) 1
Expand All @@ -10,7 +11,7 @@
-- License : BSD-style (see the file LICENSE)
-- Maintainer : Edward Kmett <ekmett@gmail.com>
-- Stability : experimental
-- Portability : Rank2Types
-- Portability : non-portable
--
-- Lenses and traversals for complex numbers
--
Expand Down
1 change: 1 addition & 0 deletions src/Data/Dynamic/Lens.hs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FlexibleContexts #-}
-----------------------------------------------------------------------------
-- |
Expand Down
7 changes: 4 additions & 3 deletions src/Data/Sequence/Lens.hs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FlexibleContexts #-}
-----------------------------------------------------------------------------
-- |
-- Module : Data.Sequence.Lens
-- Copyright : (C) 2012 Edward Kmett
-- License : BSD-style (see the file LICENSE)
-- Maintainer : Edward Kmett <ekmett@gmail.com>
-- Stability : provisional
-- Portability : portable
-- Stability : experimental
-- Portability : non-portable
--
----------------------------------------------------------------------------
module Data.Sequence.Lens
Expand Down
7 changes: 4 additions & 3 deletions src/Data/Text/Lazy/Lens.hs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 704
{-# LANGUAGE Trustworthy #-}
#endif
Expand All @@ -10,8 +11,8 @@
-- Copyright : (C) 2012 Edward Kmett
-- License : BSD-style (see the file LICENSE)
-- Maintainer : Edward Kmett <ekmett@gmail.com>
-- Stability : provisional
-- Portability : portable
-- Stability : experimental
-- Portability : non-portable
--
----------------------------------------------------------------------------
module Data.Text.Lazy.Lens
Expand Down
5 changes: 3 additions & 2 deletions src/Data/Text/Lens.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{-# LANGUAGE CPP #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FlexibleContexts #-}
#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 704
{-# LANGUAGE Trustworthy #-}
Expand All @@ -9,8 +10,8 @@
-- Copyright : (C) 2012 Edward Kmett
-- License : BSD-style (see the file LICENSE)
-- Maintainer : Edward Kmett <ekmett@gmail.com>
-- Stability : provisional
-- Portability : portable
-- Stability : experimental
-- Portability : non-portable
--
----------------------------------------------------------------------------
module Data.Text.Lens
Expand Down
5 changes: 3 additions & 2 deletions src/Data/Text/Strict/Lens.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{-# LANGUAGE CPP #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FlexibleContexts #-}
#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 704
{-# LANGUAGE Trustworthy #-}
Expand All @@ -9,8 +10,8 @@
-- Copyright : (C) 2012 Edward Kmett
-- License : BSD-style (see the file LICENSE)
-- Maintainer : Edward Kmett <ekmett@gmail.com>
-- Stability : provisional
-- Portability : portable
-- Stability : experimental
-- Portability : non-portable
--
----------------------------------------------------------------------------
module Data.Text.Strict.Lens
Expand Down
3 changes: 2 additions & 1 deletion src/GHC/Generics/Lens.hs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE LiberalTypeSynonyms #-}
{-# LANGUAGE Rank2Types #-}
-----------------------------------------------------------------------------
-- |
-- Module : GHC.Generics.Lens
Expand Down
1 change: 1 addition & 0 deletions tests/hunit.hs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TemplateHaskell #-}
module Main where

Expand Down
1 change: 1 addition & 0 deletions tests/properties.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE ExtendedDefaultRules #-}
Expand Down
1 change: 1 addition & 0 deletions tests/templates.hs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MultiParamTypeClasses #-}
Expand Down

0 comments on commit 8a9110e

Please sign in to comment.