Looping over Monads in Haskell - haskell

I am really new to Haskell, so this might be a stupid question. I have a function
foo :: Int -> IO ()
whose result will print some useful information. Now I want to do this:
do
foo 0
foo 1
foo 0
foo 2
foo 3
How can I write this as a loop? My problem is to 'concatenate' the Monads, which is done automatically by the do statement...
Thank you for your help!

mapM_ foo [0,1,0,2,3] will do the trick.
What's perhaps more important is "how does one figure that out?" Hoogle is a wonderful tool. You want to apply a function with signature Int -> IO () to a bunch of Ints to get a new IO action. The thing you're looking for will thus have signature (Int -> IO ()) -> [Int] -> IO (), so we go and ask Hoogle for functions with that signature. The second result is mapM_, whose signature is
Monad m => (a -> m b) -> [a] -> m ()
Right, so mapM_ in fact works with any monad (not just IO) and any type (not just Int). When you think about it, that's not surprising at all.

You want the mapM_ combinator, which maps a function returning a monadic value over a list, and uses the bind operator to sequence the results:
>> let foo n = putStrLn (show n ++ "!")
>> mapM_ foo [0,1,0,2,3]
0!
1!
0!
2!
3!
Sometimes people like to use the flipped version
for :: Monad m => [a] -> (a -> m b) -> m ()
for = flip mapM_
which looks more like imperative code:
>> for [1..5] $ \n ->
putStrLn ("Number: " ++ show n)
Number: 1
Number: 2
Number: 3
Number: 4
Number: 5
Note that a combinator called forM_ is defined in Control.Monad and does exactly the same thing as the combinator I've called for.

Related

How to use map to print a List in Haskell?

Sorry if I am being silly but I am a beginner in Haskell ans I am trying to make a print a List with putStrLn but i am not sure how to solve the next problem:
And I am trying to made a basic print List in Haskell with the code:
import System.IO
array = map show [1, 2, 3, 4]
main :: IO ()
main = do
map putStrLn array
but the compiler give me:
8 main.hs:7:3: error:
7 • Couldn't match expected type ‘IO ()’ with actual type ‘[IO ()]’
6 • In a stmt of a 'do' block: map putStrLn array
5 In the expression: do map putStrLn array
4 In an equation for ‘main’: main = do map putStrLn array
How I should fix it?
Haskell handles IO quite differently than other languages.
In a language like Java, System.Out.println(3) is a statement which does not evaluate to a value, so you can't even write something like x = System.Out.println(3);.
In a language like Lisp, (print 3) evaluates to 3 and, in the process of evaluation, prints 3. So saying something like (setq x (print 3)) will set the value of x to 3 and also print 3.
In Haskell, putStrLn "3" represents the command to print 3. Thus, saying x = putStrLn "3" does absolutely nothing except assign x to the command putStrLn "3".
Let's look at some types. We have
map :: (a -> b) -> [a] -> [b]
putStrLn :: String -> IO ()
Thus, we should have
map putStrLn :: [String] -> [IO ()]
map putStrLn array :: [IO ()]
In other words, map putStrLn array is a list of "IO actions" which result in a value of type () (basically, this means that executing the actions results in no extra information).
However, in order to write
main :: IO ()
main = map putStrLn array
which is what
main :: IO ()
main = do map putStrLn array
translates to, we need map putStrLn to be of type IO (), NOT of type [IO ()].
If you wish to execute an action for each element of a list, you can use the for_ function, which has type for_ :: (Foldable g, Applicative f) => g a -> (a -> f ()) -> f (). IO is Applicative and [] is Foldable, so in particular for_ :: [String] -> (String -> IO ()) -> IO () is one type that for_ can take. The code looks like
import Data.Foldable (for_)
array :: [String]
array = map show [1, 2, 3, 4]
main :: IO ()
main = for_ array putStrLn
This would be equivalent in an imperative language to
for each x in array do {
putStrLn x;
}

How to dispatch different types from a ContT?

I want to create a generalized form of IO based on ContT. I created a GADT to represent different IO actions:
data Cmd a where
PutChar :: Char -> Cmd ()
GetChar :: Cmd Char
I wrote a function that transforms these into IO commands for use in the IO monad like so:
continueIO :: Cmd a -> IO a
continueIO (PutChar c) = putChar c
continueIO GetChar = getChar
Here's what a sample usage of this should look like:
echoChar :: (Monad m) => ContT r m (Cmd a)
echoChar = ContT $ \k -> do
c <- k GetChar
k (PutChar c)
It should be run with something like runContT echoChar continueIO. However, the PutChar and GetChar commands conflict in their types. How can I dispatch both types from the same ContT?
P.S. Sorry if anything in this question is awkwardly worded. I'm trying to give myself a challenge here and I don't completely understand what I'm trying to do.
Edit: I am not restricted in my solution, and I do not have to use ContT.
Either your commands all need to be closures that return the same type (such as IO (), in which case you can’t do getChar) or you need to have a polymorphic result type that can hold either IO () or IO Char, and ContinueIO needs to take this as its argument. Then you need to decide what happens when you pass an IO Char to GetChar or nothing to PutChar. (This version could be a Monoid with <> = ContinueIO and mempty = id, and then you could foldMap over any Foldable structure.)

Trying to understand the dot operator [duplicate]

This question already has answers here:
Dot Operator in Haskell: need more explanation
(6 answers)
Closed 6 years ago.
I'm trying to understand how the dot operator works. Here's an example:
main = do
ns <- getNetworkInterfaces
mapM_ (putStr . showInterface) ns
I know that mapM_ accepts a function and Monad. "ns" is a Monad. But how actually the part (putStr . showInterface) works in terms of Haskell grammar or syntax in this particular example? Once again: in this particular example. Also, which function will be called first: putStr or showInterface?
it's just composition - it does one after the other (from the right) - so
(putStr . showInterface) n
is just
putStr (showInterface n)
so in a sense showInterface is called first
please note that your understanding is a bit flawed here - ns is not the monad here that matters (it's a list - it's the Foldable part in the newer versions of mapM_) - the monad that matters is IO and mapM_ accepts a monadic action and a list of things to put into that action (one by one) - so here every item in ns is put into the action
putStr . showInterface
and of course each one will first be used int the pure function showInterface (which obviously produces a string) and then be printed to stdout using putStr (this is the monadic action that needs the mapM_)
if in doubt check the signature
If you want to find out which part matters look at the signature
In case of mapM_ it's:
mapM_ :: (Monad m, Foldable t) => (a -> m b) -> t a -> m ()
forget the Foldable t here - it's your list:
mapM_ :: Monad m => (a -> m b) -> [a] -> m ()
now what can the m be?
Well you use putStr . showInterface for the first argument - now I don't know exactly what showInterface is - but as you compose it with putStr the resulting type should be something like
putStr . showInterface :: SomeInterfaceType -> IO ()
and now you should see that: m ~ IO, a ~ SomeInterfaceType and b ~ () - notice that the monad is IO! - and you get:
mapM_ (putStr . showInterface) :: [SomeInterfaceType] -> IO ()

Abstraction for monadic recursion with "unless"

I'm trying to work out if it's possible to write an abstraction for the following situation. Suppose I have a type a with function a -> m Bool e.g. MVar Bool and readMVar. To abstract this concept out I create a newtype wrapper for the type and its function:
newtype MPredicate m a = MPredicate (a,a -> m Bool)
I can define a fairly simple operation like so:
doUnless :: (Monad m) => Predicate m a -> m () -> m ()
doUnless (MPredicate (a,mg)) g = mg a >>= \b -> unless b g
main = do
b <- newMVar False
let mpred = MPredicate (b,readMVar)
doUnless mpred (print "foo")
In this case doUnless would print "foo". Aside: I'm not sure whether a type class might be more appropriate to use instead of a newtype.
Now take the code below, which outputs an incrementing number then waits a second and repeats. It does this until it receives a "turn off" instruction via the MVar.
foobar :: MVar Bool -> IO ()
foobar mvb = foobar' 0
where
foobar' :: Int -> IO ()
foobar' x = readMVar mvb >>= \b -> unless b $ do
let x' = x + 1
print x'
threadDelay 1000000
foobar' x'
goTillEnter :: MVar Bool -> IO ()
goTillEnter mv = do
_ <- getLine
_ <- takeMVar mv
putMVar mv True
main = do
mvb <- newMVar False
forkIO $ foobar mvb
goTillEnter mvb
Is it possible to refactor foobar so that it uses MPredicate and doUnless?
Ignoring the actual implementation of foobar' I can think of a simplistic way of doing something similar:
cycleUnless :: x -> (x -> x) -> MPredicate m a -> m ()
cycleUnless x g mp = let g' x' = doUnless mp (g' $ g x')
in g' $ g x
Aside: I feel like fix could be used to make the above neater, though I still have trouble working out how to use it
But cycleUnless won't work on foobar because the type of foobar' is actually Int -> IO () (from the use of print x').
I'd also like to take this abstraction further, so that it can work threading around a Monad. With stateful Monads it becomes even harder. E.g.
-- EDIT: Updated the below to show an example of how the code is used
{- ^^ some parent function which has the MVar ^^ -}
cycleST :: (forall s. ST s (STArray s Int Int)) -> IO ()
cycleST sta = readMVar mvb >>= \b -> unless b $ do
n <- readMVar someMVar
i <- readMVar someOtherMVar
let sta' = do
arr <- sta
x <- readArray arr n
writeArray arr n (x + i)
return arr
y = runSTArray sta'
print y
cycleST sta'
I have something similar to the above working with RankNTypes. Now there's the additional problem of trying to thread through the existential s, which is not likely to type check if threaded around through an abstraction the likes of cycleUnless.
Additionally, this is simplified to make the question easier to answer. I also use a set of semaphores built from MVar [MVar ()] similar to the skip channel example in the MVar module. If I can solve the above problem I plan to generalize the semaphores as well.
Ultimately this isn't some blocking problem. I have 3 components of the application operating in a cycle off the same MVar Bool but doing fairly different asynchronous tasks. In each one I have written a custom function that performs the appropriate cycle.
I'm trying to learn the "don't write large programs" approach. What I'd like to do is refactor chunks of code into their own mini libraries so that I'm not building a large program but assembling lots of small ones. But so far this particular abstraction is escaping me.
Any thoughts on how I might go about this are very much appreciated!
You want to cleanly combine a stateful action having side effects, a delay, and an independent stopping condition.
The iterative monad transformer from the free package can be useful in these cases.
This monad transformer lets you describe a (possibly nonending) computation as a series of discrete steps. And what's better, it let's you interleave "stepped" computations using mplus. The combined computation stops when any of the individual computations stops.
Some preliminary imports:
import Data.Bool
import Control.Monad
import Control.Monad.Trans
import Control.Monad.Trans.Iter (delay,untilJust,IterT,retract,cutoff)
import Control.Concurrent
Your foobar function could be understood as a "sum" of three things:
A computation that does nothing but reading from the MVar at each step, and finishes when the Mvar is True.
untilTrue :: (MonadIO m) => MVar Bool -> IterT m ()
untilTrue = untilJust . liftM guard . liftIO . readMVar
An infinite computation that takes a delay at each step.
delays :: (MonadIO m) => Int -> IterT m a
delays = forever . delay . liftIO . threadDelay
An infinite computation that prints an increasing series of numbers.
foobar' :: (MonadIO m) => Int -> IterT m a
foobar' x = do
let x' = x + 1
liftIO (print x')
delay (foobar' x')
With this in place, we can write foobar as:
foobar :: (MonadIO m) => MVar Bool -> m ()
foobar v = retract (delays 1000000 `mplus` untilTrue v `mplus` foobar' 0)
The neat thing about this is that you can change or remove the "stopping condition" and the delay very easily.
Some clarifications:
The delay function is not a delay in IO, it just tells the iterative monad transformer to "put the argument in a separate step".
retract brings you back from the iterative monad transformer to the base monad. It's like saying "I don't care about the steps, just run the computation". You can combine retract with cutoff if you want to limit the maximum number of iterations.
untilJustconverts a value m (Maybe a) of the base monad into a IterT m a by retrying in each step until a Just is returned. Of course, this risks non-termination!
MPredicate is rather superfluous here; m Bool can be used instead. The monad-loops package contains plenty of control structures with m Bool conditions. whileM_ in particular is applicable here, although we need to include a State monad for the Int that we're threading around:
import Control.Monad.State
import Control.Monad.Loops
import Control.Applicative
foobar :: MVar Bool -> IO ()
foobar mvb = (`evalStateT` (0 :: Int)) $
whileM_ (not <$> lift (readMVar mvb)) $ do
modify (+1)
lift . print =<< get
lift $ threadDelay 1000000
Alternatively, we can use a monadic version of unless. For some reason monad-loops doesn't export such a function, so let's write it:
unlessM :: Monad m => m Bool -> m () -> m ()
unlessM mb action = do
b <- mb
unless b action
It's somewhat more convenient and more modular in a monadic setting, since we can always go from a pure Bool to m Bool, but not vice versa.
foobar :: MVar Bool -> IO ()
foobar mvb = go 0
where
go :: Int -> IO ()
go x = unlessM (readMVar mvb) $ do
let x' = x + 1
print x'
threadDelay 1000000
go x'
You mentioned fix; sometimes people indeed use it for ad-hoc monadic loops, for example:
printUntil0 :: IO ()
printUntil0 =
putStrLn "hello"
fix $ \loop -> do
n <- fmap read getLine :: IO Int
print n
when (n /= 0) loop
putStrLn "bye"
With some juggling it's possible to use fix with multi-argument functions. In the case of foobar:
foobar :: MVar Bool -> IO ()
foobar mvb = ($(0 :: Int)) $ fix $ \loop x -> do
unlessM (readMVar mvb) $ do
let x' = x + 1
print x'
threadDelay 1000000
loop x'
I'm not sure what's your MPredicate is doing.
First, instead of newtyping a tuple, it's probably better to use a normal algebric data type
data MPredicate a m = MPredicate a (a -> m Bool)
Second, the way you use it, MPredicate is equivalent to m Bool.
Haskell is lazzy, therefore there is no need to pass, a function and it's argument (even though
it's usefull with strict languages). Just pass the result, and the function will be called when needed.
I mean, instead of passing (x, f) around, just pass f x
Of course, if you are not trying to delay the evaluation and really need at some point, the argument or the function as well as the result, a tuple is fine.
Anyway, in the case your MPredicate is only there to delay the function evaluation, MPredicat reduces to m Bool and doUnless to unless.
Your first example is strictly equivalent :
main = do
b <- newMVar False
unless (readMVar b) (print "foo")
Now, if you want to loop a monad until a condition is reach (or equivalent) you should have a look at the monad-loop package. What you are looking it at is probably untilM_ or equivalent.

How can monads determine ordering if their information is lost upon normalization?

If I understood correctly, a monad is just the implementation of a bind >>= and a return operator following certain rules which basically compose 2 functions of different return types together. So, for example, those are equivalent:
putStrLn "What is your name?"
>>= (\_ -> getLine)
>>= (\name -> putStrLn ("Welcome, " ++ name ++ "!"))
(bind (putStrLn "What is your name?")
(bind
(\_ -> getLine)
(\name -> putStrLn ("Welcome, " ++ name ++ "!"))))
But if we strongly normalize this expression, the final result will be just:
(putStrLn ("Welcome, " ++ getline ++ "!"))
The first statement (putStrLn "What is your name?") is completely lost. Also, getLine looks like a function with no arguments, which is nonsense. So how does this work, and what is the actual definition of the >>= and return functions?
Your logical misstep is that you assume certain reduction rules hold which do not. In particular, you appear to be using
f >>= (\x -> g x) ==== g f
If that held then, yes, monads would be pretty silly: (>>=) would just be flip ($). But it doesn't, in general, hold at all. In fact, the very reason it doesn't hold is what provides monads an opportunity to be interesting.
For a little bit of further exploration, here's the one monad where (>>=) == flip ($) (basically) holds.
newtype Identity a = Identity { unIdentity :: a }
To make our equations work out, we'll have to use that Identity a ~ a. This isn't strictly true, obviously, but let's pretend. In particular, Identity . unIdentity and unIdentity . Identity are both identities, no-ops, and we can freely apply Identity or unIdentity however we like to make types match
instance Functor Identity where
fmap f (Identity a) = Identity (f a)
instance Monad Identity where
return a = Identity a -- this is a no-op
ida >>= f = f (unIdentity ida)
Now, in particular, we want to examine
ida :: Identity a
f :: a -> b
ida >>= Identity . f :: Identity b
===
Identity (f (unIdentity ida)) :: Identity b
and if we throw away the Identity/unIdentity noise and thus produce the knowledge that ida = Identity a for some a
Identity (f (unIdentity ida)) :: Identity b
===
Identity (f a) :: Identity b
=== ~
f a :: b
So, while (>>=) == flip ($) forms a certain basis of intuition about (>>=)... in any circumstance more interesting than the Identity monad (and all other monads are) it doesn't hold exactly.
Seems to be a misunderstanding of how evaluation in IO proceeds in Haskell. If you look at the type signature for (>>=):
λ: :t (>>=)
(>>=) :: Monad m => m a -> (a -> m b) -> m b
It takes a monadic value parameterized by a type a, and a function which accepts a type of the same type and applies it inside the function body yielding a monadic value of type b.
The IO monad itself is a rather degenerate monad since it has special status in Haskell's implementation. A type of IO a stands for a potentially impure computation which, when performed, does some IO before returning a value of type a.
The first statement (putStrLn "What is your name?") is completely
lost.
The misunderstanding about this statement is that the value of putStrLn :: String -> IO () does in fact lose it's value in some sense, or more precisely it just yields the unit type () to the bound function after performing the IO action of printing a string to the outside world.
But if we strongly normalize this expression, the final result will be
just: (putStrLn ("Welcome, " ++ getline ++ "!"))
It's best to think of getLine :: IO String as being a computation yielding a value instead of a value itself. In this case as well the function getLine is not itself substituted in but the result of the computation it performs is, which behaves like you expect it to: getting a value from stdin and printing it back out.
It has been so long til I asked that question! The simple answer is that, no, the term I posted does not reduce to putStrLn ("Welcome, " ++ getline ++ "!"). Instead, its normal form will have the shape bind foo (\ _ -> bind bar (\ _ -> ...)), i.e., a chain of lambdas, which holds the ordering information I was worried about.
[...] what are the actual definitions for the (>>=) and return functions?
From section 6.1.7 (page 75) of the Haskell 2010 report:
The IO type serves as a tag for operations (actions) that interact with the outside world. The IO type is abstract: no constructors are visible to the user. IO is an instance of the Monad and Functor classes.
the crucial point being:
The IO type is abstract: no constructors are visible to the user.
There are no actual (written in idiomatic Haskell) definitions - it's the implementors' choice as to which model to use: state-threading, continuations, direct effects, etc. (This wasn't always the case - I provide more details here :-) We also benefit, as we're able to choose the most convenient model for the investigation being made.
So how does this work [...]?
I will choose the direct-effect model, based on examples from Philip Wadler's How to Declare an Imperative:
(* page 26, modified *)
type 'a io = oi -> 'a
infix >>=
val >>= : 'a io * ('a -> 'b io) -> 'b io
fun m >>= k = fn Oblige => let
val x = m Oblige
val y = k x Oblige
in
y
end
val return : 'a -> 'a io
fun return x = fn Oblige => x
val putc : char -> unit io
fun putc c = fn Oblige => putcML c
val getc : char io
val getc = fn Oblige => getcML ()
I'm using a new type:
datatype oi = Oblige
to reserve the unit type and its value () for the usual purpose of vacuous
results, for clarity.
(Yes - that's Standard ML: just imagine it's 1997, and you're writing a
prototype Haskell implementation ;-)
With the help of some extra definitions:
val gets : (char list) io
val putsl : char list -> unit io
that Haskell code sample, modified slightly:
putStrLn "What is your name?" >>=
(\_ -> getLine >>=
(\name -> putStrLn (greet name)))
greet :: String -> String
greet name = "Welcome, " ++ name ++ "!"
translates to:
putsl "What is your name?"
>>= (fn _ => gets
>>= (fn name => putsl (greet name))
where:
val greet : char list -> char list
fun greet name = List.concat (String.explode "Welcome, "::name::[#"!"])
All going well, the sample should simplify down to:
fun Oblige => let
val x = putsl "What is your name?" Oblige
val name = gets Oblige
val y = putsl (greet name) Oblige
in
y
end
Even though x isn't used it's still evaluated in Standard ML, which causes the prompt "What is your name?" to be displayed.
Now for a guess at the next question...Standard ML and Haskell are both functional languages - could all that oi stuff be transferred across to Haskell?
I was wrong? Meh; I'll answer it anyway - sort of; you can read about what I devised over here. If that was just too abominable to contemplate...well, here are those extra Standard ML definitions:
(* from pages 25-26, verbatim *)
val putcML : char -> unit
fun putcML c = TextIO.output1(TextIO.stdOut,c);
val getcML : unit -> char
fun getcML () = valOf(TextIO.input1(TextIO.stdIn));
(* Caution: work of SML novice... *)
val gets = fn Oblige => let
val c = getc Oblige
in
if c = #"\n" then
[]
else
let
val cs = gets Oblige
in
(c::cs)
end
end
fun putsl cs = fn Oblige => let
val _ = putsl cs Oblige
val _ = putc #"\n" Oblige
in
()
end
val puts : char list -> unit io
fun puts cs = fn Oblige => case cs of
[] => ()
| (c::cs) => let val _ = putc c Oblige in
puts cs Oblige

Resources