Getting input into Netwire programs - haskell

I'm getting started with Netwire version 5.
I have no problem writing all the wires I want to transform my inputs into my outputs.
Now the time has come to write the IO wrapper to tie in my real-world inputs, and I am a bit confused.
Am I supposed to create a custom session type for the s parameter of Wire s e m a b and embed my sensor values in there?
If so, I have these questions:
What's up with the Monoid s context of class (Monoid s, Real t) => HasTime t s | s -> t? What is it used for?
I was thinking of tacking on a Map String Double with my sensor readings, but how should my monoid crunch the dictionaries? Should it be left-biased? Right-biased? None of the above?
If not, what am I supposed to do? I want to end up with wires of the form Wire s InhibitionReason Identity () Double for some s, representing my input.
It's my understanding that I don't want or need to use the monadic m parameter of Wire for this purpose, allowing the wires themselves to be pure and confining the IO to the code that steps through the top-level wire(s). Is this incorrect?

The simplest way to put data into a Wire s e m a b is via the input a. It's possible, through the use of WPure or WGen to get data out of the state delta s or the underlying Monad m, but these take us further away from the main abstractions. The main abstractions are Arrow and Category, which only know about a b, and not about s e m.
Here's an example of a very simple program, providing input as the input a. double is the outermost wire of the program. repl is a small read-eval-print loop that calls stepWire to run the wire.
import FRP.Netwire
import Control.Wire.Core
import Prelude hiding (id, (.))
double :: Arrow a => a [x] [x]
double = arr (\xs -> xs ++ xs)
repl :: Wire (Timed Int ()) e IO String String -> IO ()
repl w = do
a <- getLine
(eb, w') <- stepWire w (Timed 1 ()) (Right a)
putStrLn . either (const "Inhibited") id $ eb
repl w'
main = repl double
Notice that we pass in the time difference to stepWire, not the total elapsed time. We can check that this is the correct thing to do by running a different top-level wire.
timeString :: (HasTime t s, Show t, Monad m) => Wire s e m a String
timeString = arr show . time
main = repl timeString
Which has the desired output:
a
1
b
2
c
3

I just solved this in an Arrow way, so this might be more composible. You can read my posts if you like. Kleisli Arrow in Netwire 5? and Console interactivity in Netwire?. The second post has a complete interactive program
First, you need this to lift Kleisli functions (That is, anything a -> m b):
mkKleisli :: (Monad m, Monoid e) => (a -> m b) -> Wire s e m a b
mkKleisli f = mkGen_ $ \a -> liftM Right $ f a
Then, assuming you want to get characters from terminal, you can lift hGetChar by doing this:
inputWire :: Wire s () IO () Char
inputWire = mkKleisli $ \_ -> hGetChar stdin
I haven't tested this runWire function (I just stripped code off from my previous posts), but it should run your wires:
runWire :: (Monad m) => Session m s -> Wire s e m () () -> m ()
runWire s w = do
(ds, s') <- stepSession s
-- | You don't really care about the () returned
(_, w') <- stepWire w ds (Right ())
runWire s' w'
You can compose the input wire wherever you like like any other Wires or Arrows. In my example, I did this (don't just copy, other parts of the program are different):
mainWire = proc _ -> do
c <- inputWire -< ()
q <- quitWire -< c
outputWire -< c
returnA -< q
Or, one-liner:
mainWire = inputWire >>> (quitWire &&& outputWire) >>> arr (\(q,_) -> q)

Related

bind a monadic value (m2 a) inside some other monad m1

Working in a Coding Dojo today I tried the following
example :: IO ()
example = do input <- getLine
parsed <- parseOnly parser input
...
where parseOnly :: Parser a -> Either String a (from attoparsec) of course the compiler complained that Either .. is not IO .. essentially telling me I am mixing monads.
Of course this can be solved by
case parseOnly parser input of .. -> ..
which is kind of unelegant, I think. Also my guess is that somebody else had this problem earlier and the solution I think is related to monad transformers, but the last bits I cannot piece together.
It also reminded me of liftIO - but this is the other way around I think which solves the problem of lifting an IO action happening inside some surrounding monad (more precisely MonadIO - say for example inside Snap when one wants to print something to stdout while getting some http).
More general this problem seems to be for a Monad m1 and a (different) Monad m2 how can I do something like
example = do a <- m1Action
b <- m2Action
..
You can't, in general. The whole do block has to be one specific monad (because example needs to have some specific type). If you could bind an arbitrary other monad inside that do block, you'd have unsafePerformIO.
Monad transformers allow you to produce one monad combining the kinds of things multiple other monads can do. But you have to decide that all the actions in your do block use the same monad transformer stack to use those, they're not a way to arbitrarily switch monads mid do-block.
Your solution with case only works because you've got a particular known monad (Either) that has a way of extracting values from inside it. Not all monads provide this, so it's impossible to build a general solution without knowing the particular monads involved. That's why the do block syntax doesn't provide such a shortcut.
In general, monad transformers are for this kind of interleaving. You can use ExceptT
example :: IO (Either String ())
example = runExceptT $ do
input <- liftIO getLine
parsed <- parseOnly parser input
...
Note that parseOnly must return ExceptT String IO a for some a. Or better ExceptT String m a for any m. Or if you want parseOnly to return Either String a it's
example :: IO (Either String ())
example = runExceptT $ do
input <- lift getLine
parsed <- ExceptT $ return $ parseOnly parser input
...
But I think all you need is just
eitherToIO :: Either String a -> IO a
eitherToIO (Left s) = error s
eitherToIO (Right x) = return x
parseOnly :: ... -> String -> Either String Int
example :: IO ()
example = do
input <- getLine
parsed <- eitherToIO $ parseOnly parser input
...
You need to make that expression type check; just as in pure code. Here,
... = do a <- act1 -- m1 monad
b <- act2 -- m2 monad
...
de-sugars to:
... = act1 >>= (\a -> act2 >>= \b -> ...)
>>= is of signature:
(>>=) :: Monad m => m a -> (a -> m b) -> m b
the outer bind is specialized with m1, so it expects that the expression inside parenthesis be of type: a -> m1 b, whereas the inner bind is specialized with m2, so the expression inside parenthesis will be of type a -> m2 b:
-- outer bind expects ( \a -> m1 b )
act1 >>= (\a -> act2 >>= \b -> ...)
-- inner bind results ( \a -> m2 b )
for this to type check, you need a function of signature m2 b -> m1 b in between the two; that is what lift does for a certain class of m2 and m1 monads: namely m1 ~ t m2 where t is an instance of MonadTrans:
lift :: (Monad m, MonadTrans t) => m a -> t m a

Partially applying a group of functions

I am working on designing a Haskell module that is designed solve a math problem, which may have various parameterizations. The module exports a function:
run_and_output_parameterization :: ProblemParams -> String -> IO ()
where the idea is that ProblemParams objects will be generated in some "controller" and called as follows:
map (\(pp, name) -> run_and_output_parameterization pp name) (zip pp_list names_list)
My question is, within the module, there are some functions such as indexing functions which I would like to partially apply for a particular parameterization. For example,
evenly_spaced_point_approx :: Int -> Int -> Int -> Double -> Double -> Int
evenly_spaced_point_approx xmin xmax xstep_i xstep_d target = pt
where
pt = max (min (round (target/xstep_d) * xstep_i) xmax) xmin
evenly_spaced_si_approx target = evenly_spaced_point_approx (_pp_si_min pp) (_pp_si_max pp) (_pp_nstep_s pp) (_pp_nstep_sd pp) target
evenly_spaced_wi_approx target = evenly_spaced_point_approx (_pp_wi_min pp) (_pp_wi_max pp) (_pp_nstep_w pp) (_pp_nstep_wd pp) target
I would like to use the functions evenly_spaced_si_approx and evenly_spaced_wi_approx within the module for a particular ProblemParameter data structure (called pp).
Is there a way I can tell Haskell to partially apply all dependent functions, or is this something I have to do by hand? Also, my apologies for being imprecise with the functional programming terminology.
If you have a lot of functions that need the same parameter, and that's the only (or last) parameter they take then you can take advantage of the Monad instance for (->) r. Alternatively, you can wrap everything in the Reader monad, whose definition is basically
newtype Reader r a = Reader { runReader :: r -> a }
instance Monad (Reader r) where
return a = Reader $ \_ -> a
m >>= f = Reader $ \r -> runReader (f (runReader m r)) r
Which, compared to the Monad instance for (->) r:
instance Monad ((->) r) where
return a = const a
m >>= f = \r -> f (m r) r
How can you use this? For example, if you had a single parameter pp :: ProblemParams, then you could write functions as
-- Some declarations
smallFunc1 :: ProblemParams -> Double
smallFunc2 :: ProblemParams -> Double
smallFunc3 :: Int -> ProblemParams -> Double
doStuff :: ProblemParams -> Double -- Just a random return type
doStuff = do -- Keep the parameter implicit
result1 <- smallFunc1 -- The ProblemParams are automatically passed
result2 <- smallFunc2
result3 <- smallFunc3 10
return $ result1 + result2 + result3
And this works quite well, you just have to make sure that all of smallFunc1, smallFunc2, and smallFunc3 10 take a ProblemParams as their last parameter (notice the inclusion of 10 with smallFunc3). The Monad instance for functions will pass that parameter implicitly in all the binds. Think of it as returning a value before that value has been computed. You get to bind the "future" return value of smallFunc1 to result1.
Alternatively, you could use the Reader monad:
type Problem a = Reader ProblemParams a
reader :: (r -> a) -> Reader r a
reader f = do
r <- ask
return $ f r
-- reader f = ask >>= return . f
smallFunc1' :: Problem Double
smallFunc1' = reader smallFunc1
smallFunc2' :: Problem Double
smallFunc2' = reader smallFunc2
smallFunc3' :: Int -> Problem Double
smallFunc3' i = reader (smallFunc3 i)
doStuff :: ProblemParams -> Double
doStuff pp = flip runReader pp $ do
result1 <- smallFunc1'
result2 <- smallFunc2'
result3 <- smallFunc3' 10
return $ result1 + result2 + result3
The reason why we have to create a reader function that lifts our primitives to the Reader monad is that Reader is actually defined in terms of the transformer ReaderT as
type Reader r a = ReaderT r Identity a
around the Identity monad.
Whichever you decide to use is up to you. I think most people would be more familiar with the Reader version, and if you decided to stack on some more transformers later it'd be really simple. The Reader monad basically helps to make the function signatures look monadic, since ProblemParams -> Double doesn't look like a normal monad signature. It will use a bit more code, but it may be that it helps you reason about your program.
Note: I haven't run any of this code, so be warned that small errors may exist. If anyone spots a problem, just let me know and I'll fix it.
An example with the Par monad and ReaderT:
type App a = ReaderT ProblemParams Par a
runApp :: ProblemParams -> App a -> a
runApp pp app = runPar $ runReaderT app pp
Then you can simply use lift to raise Par actions to App actions:
parReader :: (ProblemParams -> Par a) -> App a
parReader f = do
r <- ask
lift $ f r
-- parReader f = ask >>= lift . f
doStuff :: ProblemParams -> Double
doStuff pp = runApp pp $ do
result1 <- parReader parAction1
result2 <- parReader parAction2
result3 <- parReader (parAction3 10)
return $ result1 + result2 + result3
I'm about 99% sure that the monad stack will not affect your parallelism at all, since the Reader monad executes first, essentially applying your ProblemParams to all the functions, then it runs the Par action.

How can I write a pipe that sends downstream a list of what it receives from upstream?

I'm having a hard time to write a pipe with this signature:
toOneBigList :: (Monad m, Proxy p) => () -> Pipe p a [a] m r
It should simply take all as from upstream and send them in a list downstream.
All my attempts look fundamentally broken.
Can anybody point me in the right direction?
There are two pipes-based solutions and I'll let you pick which one you prefer.
Note: It's not clear why you output the list on the downstream interface instead of just returning it directly as a result.
Conduit-style
The first one, which is very close to the conduit-based solution uses the upcoming pipes-pase, which is basically complete and just needs documentation. You can find the latest draft on Github.
Using pipes-parse, the solution is identical to the conduit solution that Petr gave:
import Control.Proxy
import Control.Proxy.Parse
combine
:: (Monad m, Proxy p)
=> () -> Pipe (StateP [Maybe a] p) (Maybe a) [a] m ()
combine () = loop []
where
loop as = do
ma <- draw
case ma of
Nothing -> respond (reverse as)
Just a -> loop (a:as)
draw is like conduit's await: it requests a value from either the leftovers buffer (that's the StateP part) or from upstream if the buffer is empty. Nothing indicates end of file.
You can wrap a pipe that does not have an end of file signal using the wrap function from pipes-parse, which has type:
wrap :: (Monad m, Proxy p) => p a' a b' b m r -> p a' a b' (Maybe b) m s
Classic Pipes Style
The second alternative is a bit simpler. If you want to fold a given pipe you can do so directly using WriterP:
import Control.Proxy
import Control.Proxy.Trans.Writer
foldIt
:: (Monad m, Proxy p) =>
(() -> Pipe p a b m ()) -> () -> Pipe p a [b] m ()
foldIt p () = runIdentityP $ do
r <- execWriterK (liftP . p >-> toListD >-> unitU) ()
respond r
That's a higher-level description of what is going on, but it requires passing in the pipe as an explicit argument. It's up to you which one you prefer.
By the way, this is why I was asking why you want to send a single value downstream. The above is much simpler if you return the folded list:
foldIt p = execWriterK (liftP . p >-> toListD)
The liftP might not even be necessary if p is completely polymorphic in its proxy type. I only include it as a precaution.
Bonus Solution
The reason pipes-parse does not provide the toOneBigList is that it's always a pipes anti-pattern to group the results into a list. pipes has several nice features that make it possible to never have to group the input into a list, even if you are trying to yield multiple lists. For example, using respond composition you can have a proxy yield the subset of the stream it would have traversed and then inject a handler that uses that subset:
example :: (Monad m, Proxy p) => () -> Pipe p a (() -> Pipe p a a m ()) m r
example () = runIdentityP $ forever $ do
respond $ \() -> runIdentityP $ replicateM_ 3 $ request () >>= respond
printIt :: (Proxy p, Show a) => () -> Pipe p a a IO r
printIt () = runIdentityP $ do
lift $ putStrLn "Here we go!"
printD ()
useIt :: (Proxy p, Show a) => () -> Pipe p a a IO r
useIt = example />/ (\p -> (p >-> printIt) ())
Here's an example of how to use it:
>>> runProxy $ enumFromToS 1 10 >-> useIt
Here we go!
1
2
3
Here we go!
4
5
6
Here we go!
7
8
9
Here we go!
10
This means you never need to bring a single element into memory even when you need to group elements.
I'll give only a partial answer, perhaps somebody else will have a better one.
As far as I know, standard pipes have no mechanism of detecting when the other part of the pipeline terminates. The first pipe that terminates produces the final result of the pipe-line and all the others are just dropped. So if you have a pipe that consumes input forever (to eventually produce a list), it will have no chance acting and producing output when its upstream finishes. (This is intentional so that both up- and down-stream parts are dual to each other.) Perhaps this is solved in some library building on top of pipes.
The situation is different with conduit. It has consume function that combines all inputs into a list and returns (not outputs) it. Writing a function like the one you need, that outputs the list at the end, is not difficult:
import Data.Conduit
combine :: (Monad m) => Conduit a m [a]
combine = loop []
where
loop xs = await >>= maybe (yield $ reverse xs) (loop . (: xs))

Game entity modeling with netwire

I'm going to be writing a real-time game in Haskell using netwire and OpenGL. The basic idea is that each object will be represented by a wire, which will get some amount of data as input and output its state, and then I'll hook it all up into one big wire that gets the state of the GUI as input and outputs the world state, which I can then pass onto a renderer as well as some 'global' logic like collision detection.
One thing I'm not sure about is: how do I want to type the wires? Not all entities have the same input; the player is the only entity that can access the state of the key input, seeking missiles need the position of their target, etc.
One idea would be to have an ObjectInput type that gets passed to everything, but that seems bad to me since I could accidentally introduce dependencies I don't want.
On the other hand, I don't know if having a SeekerWire, a PlayerWire, an EnemyWire, etc., would be a good idea since they're almost 'identical' and so I'd have to duplicate functionality across them.
What should I do?
The inhibition monoid e is the type for inhibition exceptions. It's not something the wire produces, but takes about the same role as the e in Either e a. In other words, if you combine wires by <|>, then the output types must be equal.
Let's say your GUI events are passed to the wire through input and you have a continuous key-down event. One way to model this is the most straightforward:
keyDown :: (Monad m, Monoid e) => Key -> Wire e m GameState ()
This wire takes the current game state as input and produces a () if the key is held down. While the key is not pressed, it simply inhibits. Most applications don't really care about why a wire inhibits, so most wires inhibit with mempty.
A much more convenient way to express this event is by using a reader monad:
keyDown :: (Monoid e) => Key -> Wire e (Reader GameState) a a
What's really useful about this variant is that now you don't have to pass the game state as input. Instead this wire just acts like the identity wire when the even happens and inhibits when it doesn't:
quitScreen . keyDown Escape <|> mainGame
The idea is that when the escape key is pressed, then the event wire keyDown Escape vanishes temporarily, because it acts like the identity wire. So the whole wire acts like quitScreen assuming that it doesn't inhibit itself. Once the key is released, the event wire inhibits, so the composition with quitScreen inhibits, too. Thus the whole wire acts like mainGame.
If you want to limit the game state a wire can see, you can easily write a wire combinator for that:
trans :: (forall a. m' a -> m a) -> Wire e m' a b -> Wire e m a b
This allows you to apply withReaderT:
trans (withReaderT fullGameStateToPartialGameState)
There is a very simple and general solution to this. The key idea is that you never merge sources of different types. Instead, you only merge sources of the same type. The trick that makes this work is that you wrap the output of all your diverse sources in an algebraic data type.
I'm not really familiar with netwire, so if you don't mind I will use pipes as the example. What we want is a merge function that takes a list of sources and combines them into a single source that merges their outputs concurrently, finishing when they all complete. The key type signature is:
merge
:: (Proxy p)
=> [() -> Producer ProxyFast a IO r] -> () -> Producer p a IO ()
That just says that it takes a list of Producers of values of type a, and combines them into a single Producer of values of type a. Here's the implementation of merge, if you are curious and you want to follow along:
import Control.Concurrent
import Control.Concurrent.Chan
import Control.Monad
import Control.Proxy
fromNChan :: (Proxy p) => Int -> Chan (Maybe a) -> () -> Producer p a IO ()
fromNChan n0 chan () = runIdentityP $ loop n0 where
loop 0 = return ()
loop n = do
ma <- lift $ readChan chan
case ma of
Nothing -> loop (n - 1)
Just a -> do
respond a
loop n
toChan :: (Proxy p) => Chan ma -> () -> Consumer p ma IO r
toChan chan () = runIdentityP $ forever $ do
ma <- request ()
lift $ writeChan chan ma
merge
:: (Proxy p)
=> [() -> Producer ProxyFast a IO r] -> () -> Producer p a IO ()
merge producers () = runIdentityP $ do
chan <- lift newChan
lift $ forM_ producers $ \producer -> do
let producer' () = do
(producer >-> mapD Just) ()
respond Nothing
forkIO $ runProxy $ producer' >-> toChan chan
fromNChan (length producers) chan ()
Now, let's imagine that we have two sources of input. The first one generates the integers from 1 to 10 in one second intervals:
throttle :: (Proxy p) => Int -> () -> Pipe p a a IO r
throttle microseconds () = runIdentityP $ forever $ do
a <- request ()
respond a
lift $ threadDelay microseconds
source1 :: (Proxy p) => () -> Producer p Int IO ()
source1 = enumFromS 1 10 >-> throttle 1000000
The second source reads three Strings from user input:
source2 :: (Proxy p) => () -> Producer p String IO ()
source2 = getLineS >-> takeB_ 3
We want to combine these two sources, but their output types don't match, so we define an algebraic data type to unify their outputs into a single type:
data Merge = UserInput String | AutoInt Int deriving Show
Now we can combine them into a single list of identically typed producers by wrapping their outputs in our algebraic data type:
producers :: (Proxy p) => [() -> Producer p Merge IO ()]
producers =
[ source1 >-> mapD UserInput
, source2 >-> mapD AutoInt
]
And we can test it out really quickly:
>>> runProxy $ merge producers >-> printD
AutoInt 1
Test<Enter>
UserInput "Test"
AutoInt 2
AutoInt 3
AutoInt 4
AutoInt 5
Apple<Enter>
UserInput "Apple"
AutoInt 6
AutoInt 7
AutoInt 8
AutoInt 9
AutoInt 10
Banana<Enter>
UserInput "Banana"
>>>
Now you have a combined source. You can then write your game engine to just read from that source, pattern match on the input and then behave appropriately:
engine :: (Proxy p) => () -> Consumer p Merge IO ()
engine () = runIdentityP loop where
loop = do
m <- request ()
case m of
AutoInt n -> do
lift $ putStrLn $ "Generate unit wave #" ++ show n
loop
UserInput str -> case str of
"quit" -> return ()
_ -> loop
Let's try it:
>>> runProxy $ merge producers >-> engine
Generate unit wave #1
Generate unit wave #2
Generate unit wave #3
Test<Enter>
Generate unit wave #4
quit<Enter>
>>>
I imagine the same trick will work for netwire.
Elm has a library for Automatons which I believe is similar to what you are doing.
You could use a typeclass for each type of state you want something to have access to. Then implement each of those classes for the entire state of your game (Assuming you have 1 big fat object holding everything).
-- bfgo = Big fat game object
class HasUserInput bfgo where
mouseState :: bfgo -> MouseState
keyState :: bfgo -> KeyState
class HasPositionState bfgo where
positionState :: bfgo -> [Position] -- Use your data structure
Then when you create the functions for using the data, you simply specify the typeclasses those functions will be using.
{-#LANGUAGE RankNTypes #-}
data Player i = Player
{playerRun :: (HasUserInput i) => (i -> Player i)}
data Projectile i = Projectile
{projectileRun :: (HasPositionState i) => (i -> Projectile i)}

Semidependent Actions in Haskell

I am looking for a Haskell design to compose a chain of monadic actions (usually IO) in a manner, that later actions are dependent on previous ones but in some cases can be executed before they have finished.
The solution I came up with so far is:
type Future m a = m (m a)
Read: a monadic action, which starts some process and returns an action which will return the result of that process (possibly by waiting for this process to finish).
So in some chain a >>= b >>= c b gets an action returning a’s result. If b evaluates this action it waits for a to finish, otherwise it will be run in parallel. That also means that if some action does not require the result of the previous one as argument, it does not depend on it by definition, so the dependencies are explicit.
Some example code:
date :: Future IO String -- long process to find out the date
date = do
print "attempting to get date" -- will usually start some thread or process to compute the date
return (print "today") -- will wait for this thread or process and return the computed date
main = do
d <- date -- starts recieving the date
print "foo" -- some other process
d >>= print -- waits until the date has been computed and prints it out
Output:
"attempting to get date"
"foo"
"today"
There is a problem through: if an action decides to wait for the previous one it will always be dependent on all the others before (in my case). But in the example above if c decides to wait for b but b did not decide to wait for a, c may start before a has finished, which should not happen.
As a solution I wrote another combining operator:
(>=>) :: Monad m => Future m a -> (m a -> Future m b) -> Future m b
a >=> f = do
r1 <- a
r2 <- f r1
return (r1 >> r2)
So this will combine the “wait actions” and a >=> b >=> c will work just fine, if c waits for b this wait action will also wait for a.
However there is another problem with this approach (apart from that you need to remember to use >=> instead of >>=): the wait actions may be evaluated many times.
If b waits for a and c waits for b the wait for b will be connected to the wait for a nevertheless and thus the wait for a will be executed twice.
The actual problem is in >=>: f r1 may evaluate r1 in wich case it does not need to be sequenced with r2 in the return statement (as it already was executed and thus a has finished). But it also might not, I cannot know.
So what I basically want is exactly this but without the possibility to run the wait actions several times. Unfortunately I am not very experienced in functional design.
So I hope you can enlighten me in some way how to augment or change my design or point me to a different, more flexible approach.
Edit According to the answers so far I like to give some more clarification about what I actually want:
I do not want to defer (or even skip) the execution of actions, neither do I require threads or similar parallelism features. Actually I am calling external processes. An example would be
backup :: Future IO ExitCode
backup = do
pid <- startProcess "backup"
return (waitForProcessAndGetExitCode pid)
When I now chain actions like backup >=> otherAction, otherAction can run while the backup is running (which saves much time overall). But otherAction may require the backup to be completed, in which case it can use its parameter to wait for the backup and to check whether it was successful. Either way the backup has to be executed.
I am now looking for a nice general solution, ideally not tied to the IO monad.
Update I found a solution that worked for me. I described it in a seperate answer below.
I'm pretty sure you actually wanted this signature:
(>>=) :: Future m a -> (a -> Future m b) -> Future m b
Here's how you implement what you want:
import Control.Concurrent
import Control.Monad
import Control.Monad.Trans
newtype Future m a = Future { runFuture :: m (m a) }
instance (Monad m) => Monad (Future m) where
return = Future . return . return
m >>= f = Future $ do
fut1 <- runFuture m
return $ join $ join $ liftM (runFuture . f) fut1
instance MonadTrans Future where
lift = Future . liftM return
In other words, Future is a monad transformer, and nothing about its implementation is specialized to the IO monad. However, the following example will show how you use it in conjunction with the IO monad to chain futures:
parallel :: IO a -> Future IO a
parallel m = Future $ do
v <- newEmptyMVar
forkIO $ m >>= putMVar v
return $ takeMVar v
future1 = parallel $ do
threadDelay 1000000
putStrLn "Hello, World"
return 1
future2 n = parallel $ do
threadDelay 1000000
print n
return 2
future3 = future1 >>= future2
main = do
f <- runFuture future3
putStrLn "I'm waiting..."
r <- f
print r
I haven't yet proven that it satisfies the monad laws or the monad transformer laws, but I will try to do that and I will update you on whether or not it checks out. Until then, there might be a misplaced join somewhere in there.
Edit: Nope! Not even close. It definitely does not satisfy the monad laws. I don't know if I was close or not, but just assume this answer is incorrect for now. However, I'm kind of intrigued now and wonder if it's possible.
Perhaps one possibility is to refuse to even run f until its output is demanded:
mma >=> fab = return $ do
ma <- mma
b <- fab ma
b
Depending on just what you want, it may be important to run mma first:
mma >=> fab = do
ma <- mma
return $ do
b <- fab ma
b
If you add the restriction that you have a MonadIO instance for m, you can do something like this (from memory, untested):
share :: IO a -> IO (IO a)
share m = do
ref <- newIORef Nothing
let reader = do
cached <- readIORef ref
case cached of
Just a -> return a
Nothing -> m >>= \a -> writeIORef ref (Just a) >> return a
return reader
You can change this to share2 :: IO a -> IO a by wrapping the IORef creation in unsafePerformIO, and it's simple to generalize to any MonadIO instance.
But, depending on your problem, you might be better off with something like threads or IVar.
For cases, when you want to spark some threads and at some moment to collect results, check http://hackage.haskell.org/packages/archive/base/4.5.1.0/doc/html/Control-Concurrent-SampleVar.html and http://hackage.haskell.org/packages/archive/base/4.5.1.0/doc/html/Control-Concurrent.html#g:2 , as they seems relevant
For cases, when you need execute actions on demand, you may find this code useful
Not checked in GHC but should work after typos fixed
module Promise (SuspendedAction, createSuspendedAction, getValueFromSuspendedAction)
import Data.IORef
data Promise a = Suspended (IO a) | Done a
data SuspendedAction = SA (IORef (Promise a))
createSuspendedAction :: m a -> m (SuspendedAction a)
createSuspendedAction act = newIORef (Suspended act)
readSuspendedAction :: SuspendedAction a -> m a
readSuspendedAction (SA ref) = readIORef ref >>= \suspended -> case suspended of
Done a -> return a
Suspended sact -> sact >>= \rv -> writeIORef ref (Done rv) >> return rv
BTW, check hackage carefully, there was package which allow to execute IO actions lazily while respecting their order.
I found a solution myself, albeit not entirely for the problem I have postet.
I realized that I have to know somehow beforehand, whether or not an action is dependant from the one before. I tried various approaches and evenually came up with something I am going to describe now.
My solution allows to write code like
a :: Process IO x ()
a = independant $ do
print "start a"
return $ print "end a"
b :: Process IO x Int
b = independant $ do
print "start b"
return $ print "end b" >> return 0
c :: Process IO Int ()
c = dependant $ \x -> do
print $ "start c with " ++ show x
return $ print ("end c, started with " ++ show x)
chain = a >~ b >~ c
main = exec chain
-- outputs:
"start a" "start b" "end a" "end b" "start c with 0" "end c, started with 0"
(more examples below)
I used the following types
type Future m a = m (m a)
type Action m a b = a -> Future m b
type Process m a b = forall c. Action m c a -> Action m c b -- will need -XRank2Types
with the following primitives:
-- sequences f after g, f is dependant of g and gets its result
-- dependant :: Monad m => Action m a b -> Action m c a -> Action c b
dependant :: Monad m => Action m a b -> Process m a b
dependant f g a = join (g a) >>= f
-- sequences f after g, f is independant of g
independant :: Monad m => Future m a -> Process m b a
independant f g a = do
w1 <- g a
w2 <- f
return (w1 >> w2)
-- concenation of processes
(>~) = flip (.)
This approach allows other primitives for easier handling as well, for instance:
-- lifts a pure function into an action
pureA :: Monad m => (a -> b) -> Action m a b
pureA f a = return . return $ f a
-- makes an action wich always returns the same result
constA :: Monad m => b -> Action m a b
constA = pureA . const
-- no operation action
nop :: Monad m => Action m a ()
nop = constA ()
-- puts a sequence point
wait :: Monad m => Process m a a
wait = dependant $ pureA id
-- modify its result with a pure function
modify :: (Monad m, Functor m) => (a -> b) -> Process m a b
modify f act a = do
x <- act a
return (fmap f x)
-- makes a process, wich always returns the same result
constP :: (Monad m, Functor m) => b -> Process m a b
constP = modify . const
And finally a function to run a process:
-- executes a process
exec :: Monad m => Process m () b -> m b
exec p = join $ p nop undefined
So a few a little more complex examples:
simleI :: String -> a -> Process IO b a
simpleI name r = independant $ do
print ("start " ++ name)
return $ print ("end " ++ name) >> return r
simpleD :: (Show a, Show b) => String -> (a -> b) -> Process IO a b
simpleD name f = dependant $ \a -> do
print ("start " ++ name ++ " with " ++ show a)
let r = f a
return $ print ("end " ++ name ++ " with " ++ show r ++ " (started with " ++ show a ++ ")") >> return r
a = simpleI "a" ()
b = simpleI "b" 42
c = simpleD "c" (+1)
d = simpleI "d" ()
chain1 = a >~ b >~ c >~ d -- == d . c . b . a
chain2 = a >~ wait >~ b >~ c >~ d
chain3 = a >~ b >~ modify (+1) >~ c >~ d
main = do
exec chain1
print "---"
exec chain2
print "---"
exec chain3
Output:
"start a"
"start b"
"end a"
"end b"
"start c with 42"
"start d"
"end c with 43 (started with 42)"
"end d"
"---"
"start a"
"end a"
"start b"
"end b"
"start c with 42"
"start d"
"end c with 43 (started with 42)"
"end d"
"---"
"start a"
"start b"
"end a"
"end b"
"start c with 43"
"start d"
"end c with 44 (started with 43)"
"end d"
This is almost exactly what I want.
I am a little curious how to classify Action and Process. They are not monads. They may be Arrows, but I am too unfamiliar with Arrows to tell. Process may be an Applicative with fmap = modify and pure = const . constA oder something like that.
Please feel free to comment anything that comes in your mind about my approach, especially how to extend or simplify it.

Resources