on master help sign in
Merge pull request #635 from phadej/natural-transformation-0.4

Use natural-transformation-0.4

commit8ed7a95458c9a2af0b4858d4bdfae6138de3dea0 authorJulian Arni <jkarni@gmail.com> dateSat 19 Nov 2016, 15:14 (10 years ago) parent4fd31a6894273d
7 files changed+32−28
doc/tutorial/Server.lhs+6−6 servant/CHANGELOG.md+5 servant/servant.cabal+1 servant/src/Servant/Utils/Enter.hs+17−22 stack-ghc-7.8.4.yaml+1 stack-ghc-8.0.1.yaml+1 stack.yaml+1
doc/tutorial/Server.lhs+6−6
@@ -1044,17 +1044,17 @@ If we have a function that gets us from an `m a` to an `n a`, for any `a`, what
10441044do we have?
10451045
10461046``` haskell ignore
1047−newtype m :~> n = Nat { unNat :: forall a. m a -> n a}
1047+newtype m :~> n = NT { ($$) :: forall a. m a -> n a}
10481048```
10491049
10501050For example:
10511051
10521052``` haskell
1053−listToMaybeNat :: [] :~> Maybe
1054−listToMaybeNat = Nat listToMaybe -- from Data.Maybe
1053+listToMaybeNT :: [] :~> Maybe
1054+listToMaybeNT = NT listToMaybe -- from Data.Maybe
10551055```
10561056
1057−(`Nat` comes from "natural transformation", in case you're wondering.)
1057+(`NT` comes from "natural transformation", in case you're wondering.)
10581058
10591059So if you want to write handlers using another monad/type than `Handler`, say the `Reader String` monad, the first thing you have to
10601060prepare is a function:
@@ -1066,14 +1066,14 @@ readerToHandler :: Reader String :~> Handler
10661066Let's start with `readerToHandler'`. We obviously have to run the `Reader`
10671067computation by supplying it with a `String`, like `"hi"`. We get an `a` out
10681068from that and can then just `return` it into `ExceptT`. We can then just wrap
1069−that function with the `Nat` constructor to make it have the fancier type.
1069+that function with the `NT` constructor to make it have the fancier type.
10701070
10711071``` haskell
10721072readerToHandler' :: forall a. Reader String a -> Handler a
10731073readerToHandler' r = return (runReader r "hi")
10741074
10751075readerToHandler :: Reader String :~> Handler
1076−readerToHandler = Nat readerToHandler'
1076+readerToHandler = NT readerToHandler'
10771077```
10781078
10791079We can write some simple webservice with the handlers running in `Reader String`.
servant/CHANGELOG.md+5
@@ -1,3 +1,8 @@
1+0.10
2+------
3+
4+* Use `NT` from `natural-transformation` for `Enter`
5+
160.9.1
27------
38
servant/servant.cabal+1
@@ -58,6 +58,7 @@ library
5858 , http-api-data >= 0.3 && < 0.4
5959 , http-media >= 0.4 && < 0.7
6060 , http-types >= 0.8 && < 0.10
61+ , natural-transformation >= 0.4 && < 0.5
6162 , mtl >= 2.0 && < 2.3
6263 , mmorph >= 1 && < 1.1
6364 , text >= 1 && < 1.3
servant/src/Servant/Utils/Enter.hs+17−22
@@ -8,9 +8,13 @@
88{-# LANGUAGE TypeFamilies #-}
99{-# LANGUAGE TypeOperators #-}
1010{-# LANGUAGE UndecidableInstances #-}
11−module Servant.Utils.Enter where
11+module Servant.Utils.Enter (
12+ module Servant.Utils.Enter,
13+ -- * natural-transformation re-exports
14+ (:~>)(..),
15+ ) where
1216
13−import qualified Control.Category as C
17+import Control.Natural
1418import Control.Monad.Identity
1519import Control.Monad.Morph
1620import Control.Monad.Reader
@@ -18,7 +22,6 @@ import qualified Control.Monad.State.Lazy as LState
1822import qualified Control.Monad.State.Strict as SState
1923import qualified Control.Monad.Writer.Lazy as LWriter
2024import qualified Control.Monad.Writer.Strict as SWriter
21−import Data.Typeable
2225import Prelude ()
2326import Prelude.Compat
2427
@@ -38,57 +41,49 @@ instance (Enter b arg ret) => Enter (a -> b) arg (a -> ret) where
3841
3942-- ** Useful instances
4043
41−-- | A natural transformation from @m@ to @n@. Used to `enter` particular
42−-- datatypes.
43−newtype m :~> n = Nat { unNat :: forall a. m a -> n a} deriving Typeable
44−
45−instance C.Category (:~>) where
46− id = Nat id
47− Nat f . Nat g = Nat (f . g)
48−
4944instance Enter (m a) (m :~> n) (n a) where
50− enter (Nat f) = f
45+ enter (NT f) = f
5146
5247-- | Like `lift`.
5348liftNat :: (Control.Monad.Morph.MonadTrans t, Monad m) => m :~> t m
54−liftNat = Nat Control.Monad.Morph.lift
49+liftNat = NT Control.Monad.Morph.lift
5550
5651runReaderTNat :: r -> (ReaderT r m :~> m)
57−runReaderTNat a = Nat (`runReaderT` a)
52+runReaderTNat a = NT (`runReaderT` a)
5853
5954evalStateTLNat :: Monad m => s -> (LState.StateT s m :~> m)
60−evalStateTLNat a = Nat (`LState.evalStateT` a)
55+evalStateTLNat a = NT (`LState.evalStateT` a)
6156
6257evalStateTSNat :: Monad m => s -> (SState.StateT s m :~> m)
63−evalStateTSNat a = Nat (`SState.evalStateT` a)
58+evalStateTSNat a = NT (`SState.evalStateT` a)
6459
6560-- | Log the contents of `SWriter.WriterT` with the function provided as the
6661-- first argument, and return the value of the @WriterT@ computation
6762logWriterTSNat :: MonadIO m => (w -> IO ()) -> (SWriter.WriterT w m :~> m)
68−logWriterTSNat logger = Nat $ \x -> do
63+logWriterTSNat logger = NT $ \x -> do
6964 (a, w) <- SWriter.runWriterT x
7065 liftIO $ logger w
7166 return a
7267
7368-- | Like `logWriterTSNat`, but for strict @WriterT@.
7469logWriterTLNat :: MonadIO m => (w -> IO ()) -> (LWriter.WriterT w m :~> m)
75−logWriterTLNat logger = Nat $ \x -> do
70+logWriterTLNat logger = NT $ \x -> do
7671 (a, w) <- LWriter.runWriterT x
7772 liftIO $ logger w
7873 return a
7974
8075-- | Like @mmorph@'s `hoist`.
8176hoistNat :: (MFunctor t, Monad m) => (m :~> n) -> (t m :~> t n)
82−hoistNat (Nat n) = Nat $ hoist n
77+hoistNat (NT n) = NT $ hoist n
8378
8479-- | Like @mmorph@'s `embed`.
8580embedNat :: (MMonad t, Monad n) => (m :~> t n) -> (t m :~> t n)
86−embedNat (Nat n) = Nat $ embed n
81+embedNat (NT n) = NT $ embed n
8782
8883-- | Like @mmorph@'s `squash`.
8984squashNat :: (Monad m, MMonad t) => t (t m) :~> t m
90−squashNat = Nat squash
85+squashNat = NT squash
9186
9287-- | Like @mmorph@'s `generalize`.
9388generalizeNat :: Applicative m => Identity :~> m
94−generalizeNat = Nat (pure . runIdentity)
89+generalizeNat = NT (pure . runIdentity)
stack-ghc-7.8.4.yaml+1
@@ -15,6 +15,7 @@ extra-deps:
1515- hspec-discover-2.2.3
1616- hspec-expectations-0.7.2
1717- http-api-data-0.3
18+- natural-transformation-0.4
1819- primitive-0.6.1.0
1920- should-not-typecheck-2.1.0
2021- time-locale-compat-0.1.1.1
stack-ghc-8.0.1.yaml+1
@@ -8,4 +8,5 @@ packages:
88extra-deps:
99- http-api-data-0.3
1010- uri-bytestring-0.2.2.0
11+- natural-transformation-0.4
1112flags: {}
stack.yaml+1
@@ -9,4 +9,5 @@ packages:
99extra-deps:
1010- http-api-data-0.3
1111- servant-js-0.9 # needed for tutorial
12+- natural-transformation-0.4
1213resolver: lts-6.0