Skip to content
This repository was archived by the owner on Jan 17, 2020. It is now read-only.

Commit ca40f90

Browse files
authored
Merge pull request #4 from TinkerTravel/master
psc 0.10 support and IOSync
2 parents f29771c + 92906d0 commit ca40f90

File tree

7 files changed

+154
-81
lines changed

7 files changed

+154
-81
lines changed

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ Similarly, if we were using `Free` directly, instead of using type classes to ab
4343
```haskell
4444
data ConfigF a
4545
= ReadConfig (Config -> a)
46-
46+
4747
serverAddress :: ReaderT (PrismT' f ConfigF) (Free f) InetAddress
4848
```
4949

@@ -55,7 +55,7 @@ Therefore, MTL and direct-Free approaches can be considered alternatives to Pure
5555

5656
# Usage
5757

58-
`IO` only has one function, which should only be used in your `main`:
58+
`IO` is a newtype for `Aff`, which you can unwrap to be used in your `main`:
5959

6060
```haskell
6161
runIO :: forall a. IO a -> Aff (infinity :: INFINITY) a
@@ -72,4 +72,6 @@ Besides this, `IO` has almost all the same instances as `Aff`, and may be used
7272
in the same way. In addition, a new `MonadIO` class has been introduced which
7373
allows you to lift `IO` computations into other monads that are as powerful.
7474

75+
Similarly, `IOSync` exists as an alternative for `Eff`.
76+
7577
Happy nuke launching!

bower.json

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,17 @@
77
"output"
88
],
99
"dependencies": {
10-
"purescript-aff": "1.1.0"
10+
"purescript-aff": "^2.0.3",
11+
"purescript-control": "^2.0.0",
12+
"purescript-eff": "^2.0.0",
13+
"purescript-exceptions": "^2.0.0",
14+
"purescript-monoid": "^2.2.0",
15+
"purescript-newtype": "^1.3.0",
16+
"purescript-prelude": "^2.5.0",
17+
"purescript-tailrec": "^2.0.2",
18+
"purescript-transformers": "^2.3.0"
1119
},
1220
"devDependencies": {
13-
"purescript-psci-support": "^1.0.0"
21+
"purescript-psci-support": "^2.0.0"
1422
}
1523
}

src/Control/Monad/IO.purs

Lines changed: 49 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,87 +1,66 @@
1-
module Control.Monad.IO (IO, INFINITY, AffIO(..), runIO) where
2-
import Prelude
1+
module Control.Monad.IO
2+
( module Control.Monad.IO.Effect
3+
, IO(..)
4+
, runIO
5+
, runIO'
6+
, launchIO
7+
) where
38

4-
import Control.Alt (class Alt, alt)
5-
import Control.Alternative (class Alternative)
6-
import Control.Monad.Eff (Eff)
7-
import Control.Monad.Eff.Class (class MonadEff, liftEff)
8-
import Control.Monad.Aff (Aff)
9-
import Control.Monad.Aff.Class (class MonadAff)
10-
import Control.Monad.Eff.Exception (Error)
11-
import Control.Monad.Error.Class (class MonadError, throwError, catchError)
12-
import Control.Monad.Rec.Class (class MonadRec, tailRecM)
13-
import Control.MonadPlus (class MonadZero, class MonadPlus, empty)
14-
import Control.Parallel.Class (class MonadRace, class MonadPar, par, race, stall)
15-
import Control.Plus (class Plus)
9+
import Control.Alt (class Alt)
10+
import Control.Alternative (class Alternative)
11+
import Control.Monad.Aff (Aff, launchAff)
12+
import Control.Monad.Aff.Class (class MonadAff)
13+
import Control.Monad.Aff.Unsafe (unsafeCoerceAff)
14+
import Control.Monad.Eff.Class (class MonadEff, liftEff)
15+
import Control.Monad.Eff.Exception (Error)
16+
import Control.Monad.Eff.Unsafe (unsafeCoerceEff)
17+
import Control.Monad.Error.Class (class MonadError)
18+
import Control.Monad.IO.Effect (INFINITY)
19+
import Control.Monad.IOSync (IOSync)
20+
import Control.Monad.Rec.Class (class MonadRec)
21+
import Control.MonadZero (class MonadZero)
22+
import Control.Plus (class Plus)
23+
import Data.Monoid (class Monoid)
24+
import Data.Newtype (class Newtype, unwrap, wrap)
25+
import Prelude
1626

17-
import Data.Monoid (class Monoid, mempty)
27+
newtype IO a = IO (Aff (infinity :: INFINITY) a)
1828

19-
import Unsafe.Coerce (unsafeCoerce)
29+
runIO :: IO ~> Aff (infinity :: INFINITY)
30+
runIO = unwrap
2031

21-
foreign import data IO :: * -> *
32+
runIO' :: eff. IO ~> Aff (infinity :: INFINITY | eff)
33+
runIO' = unsafeCoerceAff <<< unwrap
2234

23-
foreign import data INFINITY :: !
35+
launchIO :: a. IO a -> IOSync Unit
36+
launchIO = void <<< liftEff <<< launchAff <<< unwrap
2437

25-
type AffIO a = Aff (infinity :: INFINITY) a
38+
derive instance newtypeIO :: Newtype (IO a) _
2639

27-
runIO :: forall a. IO a -> AffIO a
28-
runIO = unsafeCoerce
40+
derive newtype instance functorIO :: Functor IO
41+
derive newtype instance applyIO :: Apply IO
42+
derive newtype instance applicativeIO :: Applicative IO
43+
derive newtype instance bindIO :: Bind IO
44+
derive newtype instance monadIO :: Monad IO
2945

30-
toIO :: forall e a. Aff e a -> IO a
31-
toIO = unsafeCoerce
46+
derive newtype instance monadRecIO :: MonadRec IO
3247

33-
instance semigroupIO :: (Semigroup a) => Semigroup (IO a) where
34-
append a b = toIO (append (runIO a) (runIO b))
48+
derive newtype instance semigroupIO :: (Semigroup a) => Semigroup (IO a)
3549

36-
instance monoidIO :: (Monoid a) => Monoid (IO a) where
37-
mempty = toIO (pure mempty)
50+
derive newtype instance monoidIO :: (Monoid a) => Monoid (IO a)
3851

39-
instance functorIO :: Functor IO where
40-
map f fa = toIO (map f (runIO fa))
52+
instance monadAffIO :: MonadAff eff IO where
53+
liftAff = wrap <<< unsafeCoerceAff
4154

42-
instance applyIO :: Apply IO where
43-
apply ff fa = toIO (apply (runIO ff) (runIO fa))
55+
instance monadEffIO :: MonadEff eff IO where
56+
liftEff = wrap <<< liftEff <<< unsafeCoerceEff
4457

45-
instance applicativeIO :: Applicative IO where
46-
pure v = toIO (pure v)
58+
derive newtype instance monadErrorIO :: MonadError Error IO
4759

48-
instance bindIO :: Bind IO where
49-
bind fa f = toIO (bind (runIO fa) (unsafeCoerce f))
60+
derive newtype instance altIO :: Alt IO
5061

51-
instance monadIO :: Monad IO
62+
derive newtype instance plusIO :: Plus IO
5263

53-
instance monadEffIO :: MonadEff e IO where
54-
liftEff = liftEff'
55-
where
56-
liftEff' :: forall a. Eff e a -> IO a
57-
liftEff' eff = toIO (liftEff eff :: Aff e a)
64+
derive newtype instance alternativeIO :: Alternative IO
5865

59-
instance monadAffIO :: MonadAff e IO where
60-
liftAff = toIO
61-
62-
instance monadErrorIO :: MonadError Error IO where
63-
throwError e = toIO (throwError e)
64-
65-
catchError io f = toIO (catchError (runIO io) (runIO <$> f))
66-
67-
instance altIO :: Alt IO where
68-
alt a1 a2 = toIO (alt (runIO a1) (runIO a2))
69-
70-
instance plusIO :: Plus IO where
71-
empty = toIO empty
72-
73-
instance alternativeIO :: Alternative IO
74-
75-
instance monadZero :: MonadZero IO
76-
77-
instance monadPlusIO :: MonadPlus IO
78-
79-
instance monadRecIO :: MonadRec IO where
80-
tailRecM f a = toIO (tailRecM (unsafeCoerce f) a)
81-
82-
instance monadParIO :: MonadPar IO where
83-
par f ma mb = toIO (par f (runIO ma) (runIO mb))
84-
85-
instance monadRaceIO :: MonadRace IO where
86-
stall = toIO stall
87-
race a1 a2 = toIO (race (runIO a1) (runIO a2))
66+
derive newtype instance monadZeroIO :: MonadZero IO

src/Control/Monad/IO/Class.purs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
module Control.Monad.IO.Class where
2-
import Control.Category (id)
3-
import Control.Monad (class Monad)
4-
import Control.Monad.IO (IO)
52

6-
class Monad m <= MonadIO m where
7-
liftIO :: forall a. IO a -> m a
3+
import Control.Monad.IO (IO)
4+
import Prelude
85

9-
instance monadIOIO :: MonadIO IO where
10-
liftIO = id
6+
class (Monad m) <= MonadIO m where
7+
liftIO :: IO ~> m
8+
9+
instance monadIOIO :: MonadIO IO where
10+
liftIO = id

src/Control/Monad/IO/Effect.purs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module Control.Monad.IO.Effect
2+
( INFINITY
3+
) where
4+
5+
foreign import data INFINITY :: Effect

src/Control/Monad/IOSync.purs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
module Control.Monad.IOSync
2+
( module Control.Monad.IO.Effect
3+
, IOSync(..)
4+
, runIOSync
5+
, runIOSync'
6+
) where
7+
8+
import Control.Alt (class Alt)
9+
import Control.Alternative (class Alternative)
10+
import Control.Monad.Eff (Eff)
11+
import Control.Monad.Eff.Class (class MonadEff, liftEff)
12+
import Control.Monad.Eff.Exception (Error, catchException, error, throwException)
13+
import Control.Monad.Eff.Unsafe (unsafeCoerceEff)
14+
import Control.Monad.Error.Class (class MonadError, catchError, throwError)
15+
import Control.Monad.IO.Effect (INFINITY)
16+
import Control.Monad.Rec.Class (class MonadRec)
17+
import Control.MonadZero (class MonadZero)
18+
import Control.Plus (class Plus)
19+
import Data.Monoid (class Monoid, mempty)
20+
import Data.Newtype (class Newtype, unwrap, wrap)
21+
import Prelude
22+
23+
newtype IOSync a = IOSync (Eff (infinity :: INFINITY) a)
24+
25+
runIOSync :: IOSync ~> Eff (infinity :: INFINITY)
26+
runIOSync = unwrap
27+
28+
runIOSync' :: eff. IOSync ~> Eff (infinity :: INFINITY | eff)
29+
runIOSync' = unsafeCoerceEff <<< unwrap
30+
31+
derive instance newtypeIOSync :: Newtype (IOSync a) _
32+
33+
derive newtype instance functorIOSync :: Functor IOSync
34+
derive newtype instance applyIOSync :: Apply IOSync
35+
derive newtype instance applicativeIOSync :: Applicative IOSync
36+
derive newtype instance bindIOSync :: Bind IOSync
37+
derive newtype instance monadIOSync :: Monad IOSync
38+
39+
derive newtype instance monadRecIOSync :: MonadRec IOSync
40+
41+
instance semigroupIOSync :: (Semigroup a) => Semigroup (IOSync a) where
42+
append a b = append <$> a <*> b
43+
44+
instance monoidIOSync :: (Monoid a) => Monoid (IOSync a) where
45+
mempty = pure mempty
46+
47+
instance monadEffIOSync :: MonadEff eff IOSync where
48+
liftEff = wrap <<< unsafeCoerceEff
49+
50+
instance monadErrorIOSync :: MonadError Error IOSync where
51+
catchError a k = liftEff $
52+
catchException (\e -> unwrap $ k e) (unsafeCoerceEff $ unwrap a)
53+
throwError = liftEff <<< throwException
54+
55+
instance altIOSync :: Alt IOSync where
56+
alt a b = a `catchError` const b
57+
58+
instance plusIOSync :: Plus IOSync where
59+
empty = throwError $ error "plusIOSync.empty"
60+
61+
instance alternativeIOSync :: Alternative IOSync
62+
63+
instance monadZeroIOSync :: MonadZero IOSync
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
module Control.Monad.IOSync.Class where
2+
3+
import Control.Monad.Eff.Class (liftEff)
4+
import Control.Monad.IO (IO)
5+
import Control.Monad.IOSync (IOSync)
6+
import Data.Newtype (unwrap, wrap)
7+
import Prelude
8+
9+
class (Monad m) <= MonadIOSync m where
10+
liftIOSync :: IOSync ~> m
11+
12+
instance monadIOSyncIOSync :: MonadIOSync IOSync where
13+
liftIOSync = id
14+
15+
instance monadIOSyncIO :: MonadIOSync IO where
16+
liftIOSync = wrap <<< liftEff <<< unwrap

0 commit comments

Comments
 (0)