From 8d2fe3aa2739f6069b1a9c13170165a3f226d88f Mon Sep 17 00:00:00 2001 From: Ryan Hendrickson Date: Thu, 4 Feb 2021 12:22:51 -0500 Subject: [PATCH] Refactor functors and related packages This is part of a set of commits that rearrange the dependencies between multiple packages. The immediate motivation is to allow certain newtypes to be reused between `profunctor` and `bifunctors`, but this particular approach goes a little beyond that in two ways: first, it attempts to move data types (`either`, `tuple`) toward the bottom of the dependency stack; and second, it tries to ensure no package comes between `functors` and the packages most closely related to it, in order to open the possibility of merging those packages together (which may be desirable if at some point in the future additional newtypes are added which reveal new and exciting constraints on the module dependency graph). --- CHANGELOG.md | 3 ++ bower.json | 1 - src/Data/Profunctor/Clown.purs | 27 -------------- src/Data/Profunctor/Costar.purs | 62 --------------------------------- src/Data/Profunctor/Cowrap.purs | 21 ----------- src/Data/Profunctor/Joker.purs | 43 ----------------------- src/Data/Profunctor/Wrap.purs | 20 ----------- 7 files changed, 3 insertions(+), 174 deletions(-) delete mode 100644 src/Data/Profunctor/Clown.purs delete mode 100644 src/Data/Profunctor/Costar.purs delete mode 100644 src/Data/Profunctor/Cowrap.purs delete mode 100644 src/Data/Profunctor/Joker.purs delete mode 100644 src/Data/Profunctor/Wrap.purs diff --git a/CHANGELOG.md b/CHANGELOG.md index 3398647..7c19d2d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,8 +7,11 @@ Notable changes to this project are documented in this file. The format is based Breaking changes: - Added support for PureScript 0.14 and dropped support for all previous versions (#35) - Removed `Costrong` and `Cochoice` from `Costar` (#38) +- `Clown`, `Costar`, `Cowrap`, and `Joker` have been moved to the `Data.Functors` module in the `purescript-functors` package, so that the same types can also be used as bifunctors; `Cowrap` was renamed to `Flip` (#41) +- `Wrap` was deleted; it is expected that any instances of `Profunctor` will be accompanied by a corresponding instance of `Functor` (#41) New features: +- This package no longer depends on the `purescript-contravariant` package (#41) Bugfixes: diff --git a/bower.json b/bower.json index f363c5b..c3c3d81 100644 --- a/bower.json +++ b/bower.json @@ -21,7 +21,6 @@ "package.json" ], "dependencies": { - "purescript-contravariant": "master", "purescript-control": "master", "purescript-distributive": "master", "purescript-either": "master", diff --git a/src/Data/Profunctor/Clown.purs b/src/Data/Profunctor/Clown.purs deleted file mode 100644 index 957bbe2..0000000 --- a/src/Data/Profunctor/Clown.purs +++ /dev/null @@ -1,27 +0,0 @@ -module Data.Profunctor.Clown where - -import Prelude - -import Data.Profunctor (class Profunctor) -import Data.Newtype (class Newtype) -import Data.Functor.Contravariant (class Contravariant, cmap) - --- | Makes a trivial `Profunctor` for a `Contravariant` functor. -newtype Clown :: forall k1 k2. (k1 -> Type) -> k1 -> k2 -> Type -newtype Clown f a b = Clown (f a) - -derive instance newtypeClown :: Newtype (Clown f a b) _ -derive newtype instance eqClown :: Eq (f a) => Eq (Clown f a b) -derive newtype instance ordClown :: Ord (f a) => Ord (Clown f a b) - -instance showClown :: Show (f a) => Show (Clown f a b) where - show (Clown x) = "(Clown " <> show x <> ")" - -instance functorClown :: Functor (Clown f a) where - map _ (Clown a) = Clown a - -instance profunctorClown :: Contravariant f => Profunctor (Clown f) where - dimap f g (Clown a) = Clown (cmap f a) - -hoistClown :: forall f g a b. (f ~> g) -> Clown f a b -> Clown g a b -hoistClown f (Clown a) = Clown (f a) diff --git a/src/Data/Profunctor/Costar.purs b/src/Data/Profunctor/Costar.purs deleted file mode 100644 index 8c7cba9..0000000 --- a/src/Data/Profunctor/Costar.purs +++ /dev/null @@ -1,62 +0,0 @@ -module Data.Profunctor.Costar where - -import Prelude - -import Control.Comonad (class Comonad, extract) -import Control.Extend (class Extend, (=<=)) - -import Data.Distributive (class Distributive, distribute) -import Data.Functor.Invariant (class Invariant, imapF) -import Data.Newtype (class Newtype) -import Data.Profunctor (class Profunctor, lcmap) -import Data.Profunctor.Closed (class Closed) -import Data.Profunctor.Strong (class Strong) -import Data.Tuple (Tuple(..), fst, snd) - --- | `Costar` turns a `Functor` into a `Profunctor` "backwards". --- | --- | `Costar f` is also the co-Kleisli category for `f`. -newtype Costar :: forall k. (k -> Type) -> k -> Type -> Type -newtype Costar f b a = Costar (f b -> a) - -derive instance newtypeCostar :: Newtype (Costar f a b) _ - -instance semigroupoidCostar :: Extend f => Semigroupoid (Costar f) where - compose (Costar f) (Costar g) = Costar (f =<= g) - -instance categoryCostar :: Comonad f => Category (Costar f) where - identity = Costar extract - -instance functorCostar :: Functor (Costar f a) where - map f (Costar g) = Costar (f <<< g) - -instance invariantCostar :: Invariant (Costar f a) where - imap = imapF - -instance applyCostar :: Apply (Costar f a) where - apply (Costar f) (Costar g) = Costar \a -> f a (g a) - -instance applicativeCostar :: Applicative (Costar f a) where - pure a = Costar \_ -> a - -instance bindCostar :: Bind (Costar f a) where - bind (Costar m) f = Costar \x -> case f (m x) of Costar g -> g x - -instance monadCostar :: Monad (Costar f a) - -instance distributiveCostar :: Distributive (Costar f a) where - distribute f = Costar \a -> map (\(Costar g) -> g a) f - collect f = distribute <<< map f - -instance profunctorCostar :: Functor f => Profunctor (Costar f) where - dimap f g (Costar h) = Costar (map f >>> h >>> g) - -instance strongCostar :: Comonad f => Strong (Costar f) where - first (Costar f) = Costar \x -> Tuple (f (map fst x)) (snd (extract x)) - second (Costar f) = Costar \x -> Tuple (fst (extract x)) (f (map snd x)) - -instance closedCostar :: Functor f => Closed (Costar f) where - closed (Costar f) = Costar \g x -> f (map (_ $ x) g) - -hoistCostar :: forall f g a b. (g ~> f) -> Costar f a b -> Costar g a b -hoistCostar f (Costar g) = Costar (lcmap f g) diff --git a/src/Data/Profunctor/Cowrap.purs b/src/Data/Profunctor/Cowrap.purs deleted file mode 100644 index 89f0bf3..0000000 --- a/src/Data/Profunctor/Cowrap.purs +++ /dev/null @@ -1,21 +0,0 @@ -module Data.Profunctor.Cowrap where - -import Prelude - -import Data.Newtype (class Newtype) -import Data.Functor.Contravariant (class Contravariant) -import Data.Profunctor (class Profunctor, lcmap) - --- | Provides a `Contravariant` over the first argument of a `Profunctor`. -newtype Cowrap :: forall k1 k2. (k1 -> k2 -> Type) -> k2 -> k1 -> Type -newtype Cowrap p b a = Cowrap (p a b) - -derive instance newtypeCowrap :: Newtype (Cowrap p b a) _ -derive newtype instance eqCowrap :: Eq (p a b) => Eq (Cowrap p b a) -derive newtype instance ordCowrap :: Ord (p a b) => Ord (Cowrap p b a) - -instance showCowrap :: Show (p a b) => Show (Cowrap p b a) where - show (Cowrap x) = "(Cowrap " <> show x <> ")" - -instance contravariantCowrap :: Profunctor p => Contravariant (Cowrap p b) where - cmap f (Cowrap a) = Cowrap (lcmap f a) diff --git a/src/Data/Profunctor/Joker.purs b/src/Data/Profunctor/Joker.purs deleted file mode 100644 index b06e9ac..0000000 --- a/src/Data/Profunctor/Joker.purs +++ /dev/null @@ -1,43 +0,0 @@ -module Data.Profunctor.Joker where - -import Prelude - -import Data.Either (Either(..)) -import Data.Newtype (class Newtype, un) -import Data.Profunctor (class Profunctor) -import Data.Profunctor.Choice (class Choice) - --- | Makes a trivial `Profunctor` for a covariant `Functor`. -newtype Joker :: forall k1 k2. (k1 -> Type) -> k2 -> k1 -> Type -newtype Joker f a b = Joker (f b) - -derive instance newtypeJoker :: Newtype (Joker f a b) _ -derive newtype instance eqJoker :: Eq (f b) => Eq (Joker f a b) -derive newtype instance ordJoker :: Ord (f b) => Ord (Joker f a b) - -instance showJoker :: Show (f b) => Show (Joker f a b) where - show (Joker x) = "(Joker " <> show x <> ")" - -instance functorJoker :: Functor f => Functor (Joker f a) where - map f (Joker a) = Joker (map f a) - -instance profunctorJoker :: Functor f => Profunctor (Joker f) where - dimap f g (Joker a) = Joker (map g a) - -instance clownJoker :: Functor f => Choice (Joker f) where - left (Joker f) = Joker $ map Left f - right (Joker f) = Joker $ map Right f - -instance applyJoker :: Apply f => Apply (Joker f a) where - apply (Joker f) (Joker g) = Joker $ apply f g - -instance applicativeJoker :: Applicative f => Applicative (Joker f a) where - pure = Joker <<< pure - -instance bindJoker :: Bind f => Bind (Joker f a) where - bind (Joker ma) amb = Joker $ ma >>= (amb >>> un Joker) - -instance monadJoker :: Monad m => Monad (Joker m a) - -hoistJoker :: forall f g a b. (f ~> g) -> Joker f a b -> Joker g a b -hoistJoker f (Joker a) = Joker (f a) diff --git a/src/Data/Profunctor/Wrap.purs b/src/Data/Profunctor/Wrap.purs deleted file mode 100644 index e5972fb..0000000 --- a/src/Data/Profunctor/Wrap.purs +++ /dev/null @@ -1,20 +0,0 @@ -module Data.Profunctor.Wrap where - -import Prelude - -import Data.Newtype (class Newtype) -import Data.Profunctor (class Profunctor, rmap) - --- | Provides a `Functor` over the second argument of a `Profunctor`. -newtype Wrap :: forall k1 k2. (k1 -> k2 -> Type) -> k1 -> k2 -> Type -newtype Wrap p a b = Wrap (p a b) - -derive instance newtypeWrap :: Newtype (Wrap p a b) _ -derive newtype instance eqWrap :: Eq (p a b) => Eq (Wrap p a b) -derive newtype instance ordWrap :: Ord (p a b) => Ord (Wrap p a b) - -instance showWrap :: Show (p a b) => Show (Wrap p a b) where - show (Wrap x) = "(Wrap " <> show x <> ")" - -instance functorWrap :: Profunctor p => Functor (Wrap p a) where - map f (Wrap a) = Wrap (rmap f a)