Sequencing bind with pure functions - haskell

I often find myself wanting to insert regular functions into a "binded" sequence. Like in this contrived example:
getLine >>= lift (map toUpper) >>= putStrLn
I need to define the lift function lift :: (a -> b) -> a -> m b to make this work. Problem is I don't know of such a function, and Hoogle doesn't seem to either. I find this odd since this makes totally sense to me.
Now, there are probably other ways to make this work, but I like the way point-free style code allows me to scan the line in one pass to figure out what is happening.
let lift f x = return (f x) in
getLine >>= lift (map toUpper) >>= putStrLn
My question boils down to this: am I missing something or how come there isn't a function like lift. My experience in Haskell is still very limited, so I am assuming that most people solve this in a different way. Can someone explain to me the idiomatic way of solving this.

There are three idiomatic ways.
Don't use bind; use the first hit on your Hoogle search instead:
liftM (map toUpper) getLine >>= putStrLn
There are a variety of alternative spellings of liftM, such as fmap or (<$>).
Inline the lift function you defined:
getLine >>= return . map toUpper >>= putStrLn
Use the monad laws to fuse the last two binds in option 2:
getLine >>= putStrLn . map toUpper

Use the Functor instance in such cases:
> import Data.Char
> import Data.Functor
> map toUpper <$> getLine >>= putStrLn
foo
FOO
>

Related

Lazy evaluation of IO actions

I'm trying to write code in source -> transform -> sink style, for example:
let (|>) = flip ($)
repeat 1 |> take 5 |> sum |> print
But would like to do that using IO. I have this impression that my source can be an infinite list of IO actions, and each one gets evaluated once it is needed downstream. Something like this:
-- prints the number of lines entered before "quit" is entered
[getLine..] >>= takeWhile (/= "quit") >>= length >>= print
I think this is possible with the streaming libraries, but can it be done along the lines of what I'm proposing?
Using the repeatM, takeWhile and length_ functions from the streaming library:
import Streaming
import qualified Streaming.Prelude as S
count :: IO ()
count = do r <- S.length_ . S.takeWhile (/= "quit") . S.repeatM $ getLine
print r
This seems to be in that spirit:
let (|>) = flip ($)
let (.>) = flip (.)
getContents >>= lines .> takeWhile (/= "quit") .> length .> print
The issue here is that Monad is not the right abstraction for this, and attempting to do something like this results in a situation where referential transparency is broken.
Firstly, we can do a lazy IO read like so:
module Main where
import System.IO.Unsafe (unsafePerformIO)
import Control.Monad(forM_)
lazyIOSequence :: [IO a] -> IO [a]
lazyIOSequence = pure . go where
go :: [IO a] -> [a]
go (l:ls) = (unsafePerformIO l):(go ls)
main :: IO ()
main = do
l <- lazyIOSequence (repeat getLine)
forM_ l putStrLn
This when run will perform cat. It will read lines and output them. Everything works fine.
But consider changing the main function to this:
main :: IO ()
main = do
l <- lazyIOSequence (map (putStrLn . show) [1..])
putStrLn "Hello World"
This outputs Hello World only, as we didn't need to evaluate any of l. But now consider replacing the last line like the following:
main :: IO ()
main = do
x <- lazyIOSequence (map (putStrLn . show) [1..])
seq (head x) putStrLn "Hello World"
Same program, but the output is now:
1
Hello World
This is bad, we've changed the results of a program just by evaluating a value. This is not supposed to happen in Haskell, when you evaluate something it should just evaluate it, not change the outside world.
So if you restrict your IO actions to something like reading from a file nothing else is reading from, then you might be able to sensibly lazily evaluate things, because when you read from it in relation to all the other IO actions your program is taking doesn't matter. But you don't want to allow this for IO in general, because skipping actions or performing them in a different order can matter (and above, certainly does). Even in the reading a file lazily case, if something else in your program writes to the file, then whether you evaluate that list before or after the write action will affect the output of your program, which again, breaks referential transparency (because evaluation order shouldn't matter).
So for a restricted subset of IO actions, you can sensibly define Functor, Applicative and Monad on a stream type to work in a lazy way, but doing so in the IO Monad in general is a minefield and often just plain incorrect. Instead you want a specialised streaming type, and indeed Conduit defines Functor, Applicative and Monad on a lot of it's types so you can still use all your favourite functions.

How do I "continue" in a `Monad` loop?

Often times I found myself in need of skipping the rest of the iteration (like continue in C) in Haskell:
forM_ [1..100] $ \ i ->
a <- doSomeIO
when (not $ isValid1 a) <skip_rest_of_the_iteration>
b <- doSomeOtherIO a
when (not $ isValid2 b) <skip_rest_of_the_iteration>
...
However, I failed to find an easy way to do so. The only way I am aware of is probably the Trans.Maybe, but is it necessary to use a monad transform to achieve something so trivial?
Remember that loops like this in Haskell are not magic...they're just normal first-class things that you can write yourself.
For what it's worth, I don't think it's too useful to think of MaybeT as a Monad transformer. To me, MaybeT is just a newtype wrapper to give an alternative implementation of (>>=)...just like how you use Product, Sum, First, And, etc. to give alternative implementations of mappend and mempty.
Right now, (>>=) for you is IO a -> (a -> IO b) -> IO b. But it'd be more useful to have (>>=) here be IO (Maybe a) -> (a -> IO (Maybe b) -> IO (Maybe b). As soon as you get to the first action that returns a Nothing, it's really impossible to "bind" any further. That's exactly what MaybeT gives you. You also get a "custom instance" of guard, guard :: Bool -> IO (Maybe a), instead of guard :: IO a.
forM_ [1..100] $ \i -> runMaybeT $ do
a <- lift doSomeIO
guard (isValid1 a)
b <- lift $ doSomeOtherIO a
guard (isValid2 b)
...
and that's it :)
MaybeT is not magic either, and you can achieve basically the same effect by using nested whens. It's not necessary, it just makes things a lot simpler and cleaner :)
Here's how you would do it using bare-bones recursion:
loop [] = return () -- done with the loop
loop (x:xs) =
do a <- doSomeIO
if ...a...
then return () -- exit the loop
else do -- continuing with the loop
b <- doSomeMoreIO
if ...b...
then return () -- exit the loop
else do -- continuing with the loop
...
loop xs -- perform the next iteration
and then invoke it with:
loop [1..100]
You can tidy this up a bit with the when function from Control.Monad:
loop [] = return ()
loop (x:xs) =
do a <- doSomeIO
when (not ...a...) $ do
b <- doSomeMoreIO
when (not ...b...) $ do
...
loop xs
There is also unless in Control.Monad which you might prefer to use.
Using #Ørjan Johansen 's helpful advice, here is an simple example:
import Control.Monad
loop [] = return ()
loop (x:xs) = do
putStrLn $ "x = " ++ show x
a <- getLine
when (a /= "stop") $ do
b <- getLine
when (b /= "stop") $ do
print $ "iteration: " ++ show x ++ ": a = " ++ a ++ " b = " ++ b
loop xs
main = loop [1..3]
If you want to loop over a list or other container to perform actions and/or produce a summary value, and you're finding the usual convenience tools like for_ and foldM aren't good enough for the job, you might want to consider foldr, which is plenty strong enough for the job. When you're not really looping over a container, you can use plain old recursion or pull in something like https://hackage.haskell.org/package/loops or (for a very different flavor) https://hackage.haskell.org/package/machines or perhaps https://hackage.haskell.org/package/pipes.

Idiomatic Haskell syntax without do-blocks or accumulating parentheses?

I'm fairly new to Haskell and have been trying to find a way to pass multiple IO-tainted values to a function to deal with a C library. Most people seem to use the <- operator inside a do block, like this:
g x y = x ++ y
interactiveConcat1 = do {x <- getLine;
y <- getLine;
putStrLn (g x y);
return ()}
This makes me feel like I'm doing C, except emacs can't auto-indent. I tried to write this in a more Lispy style:
interactiveConcat2 = getLine >>= (\x ->
getLine >>= (\y ->
putStrLn (g x y) >>
return () ))
That looks like a mess, and has a string of closed parentheses you have to count at the end (except again, emacs can reliably assist with this task in Lisp, but not in Haskell). Yet another way is to say
import Control.Applicative
interactiveConcat3 = return g <*> getLine <*> getLine >>= putStrLn
which looks pretty neat but isn't part of the base language.
Is there any less laborious notation for peeling values out of the IO taint boxes? Perhaps there is a cleaner way using a lift* or fmap? I hope it isn't too subjective to ask what is considered "idiomatic"?
Also, any tips for making emacs cooperate better than (Haskell Ind) mode would be greatly appreciated. Thanks!
John
Edit: I stumbled across https://wiki.haskell.org/Do_notation_considered_harmful and realized that the nested parentheses in the lambda chain I wrote is not necessary. However it seems the community (and ghc implementors) have embraced the Applicative-inspired style using , <*>, etc, which seems to make the code easier to read in spite of the headaches with figuring out operator precedence.
Note: This post is written in literate Haskell. You can save it as Main.lhs and try it in your GHCi.
A short remark first: you can get rid of the semicolons and the braces in do. Also, putStrLn has type IO (), so you don't need return ():
interactiveConcat1 = do
x <- getLine
y <- getLine
putStrLn $ g x y
We're going to work with IO, so importing Control.Applicative or Control.Monad will come in handy:
> module Main where
> import Control.Applicative
> -- Repeat your definition for completeness
> g :: [a] -> [a] -> [a]
> g = (++)
You're looking for something like this:
> interactiveConcat :: IO ()
> interactiveConcat = magic g getLine getLine >>= putStrLn
What type does magic need? It returns a IO String, takes a function that returns an String and takes usual Strings, and takes two IO Strings:
magic :: (String -> String -> String) -> IO String -> IO String -> IO String
We can probably generalize this type to
> magic :: (a -> b -> c) -> IO a -> IO b -> IO c
A quick hoogle search reveals that there are already two functions with almost that type: liftA2 from Control.Applicative and liftM2 from Control.Monad. They're defined for every Applicative and – in case of liftM2 – Monad. Since IO is an instance of both, you can choose either one:
> magic = liftA2
If you use GHC 7.10 or higher, you can also use <$> and <*> without import and write interactiveConcat as
interactiveConcat = g <$> getLine <*> getLine >>= putStrLn
For completeness, lets add a main so that we can easily check this functionality via runhaskell Main.lhs:
> main :: IO ()
> main = interactiveConcat
A simple check shows that it works as intended:
$ echo "Hello\nWorld" | runhaskell Main.lhs
HelloWorld
References
Applicative in the Typeclassopedia
The section "Some useful monadic functions" of LYAH's chapter "For a Few Monads More".
You can use liftA2 (or liftM2 from Control.Monad):
import Control.Applicative (liftA2)
liftA2 g getLine getLine >>= putStrLn

How to avoid superfluous variables in do notation?

Say in a Haskell do-notation block, I wish to have a variable is_root indicating if I am root:
import System.Posix.User
main = do
uid <- getRealUserID
is_root <- return $ uid == 0
That annoying uid variable is only used in that one place. I wish instead I could write this:
main = do
is_root <- getRealUserID == 0
But of course that won't compile.
How can I get rid of superfluous variables like uid? Here's the best I've come up with:
import System.Posix.User
main = do
is_root <- getRealUserID >>= return . ((==) 0)
Blech! Is there a nicer way?
One way is
fmap (== 0) getRealUserID
(I assume your goal is to limit the scope of uid, not to just be pointfree for its own sake)
In a simple case like this, #pdw's answer is probably the way to go. The operators <$> and <*> from Control.Applicative are particularly helpful here.
foo = do
are_same <- (==) <$> doThis <*> doThat
In slightly more complicated situations, you could use a nested-do:
complicatedEq :: This -> That -> IO Bool
main = do
are_same <- do
this <- doThis
that <- doThatBasedOn this
complicatedEq this that
... rest ...
Anything significantly long probably deserves to be its own function.

Haskell monadic IO

compute fp = do
text <- readFile fp
let (a,b) = sth text
let x = data b
--g <- x
putStr $ print_matrix $ fst $ head $ x
It works when i get only first element but i want do this for all element on the list of pair.
When i write g<- x i got Couldn't match expected type `IO t0'
with actual type [([[Integer]], [[Integer]])]
You're inside the IO Monad here, so any time you write a "bind" arrow <-, the thing on the right side has to be an IO operation. So the short answer is, you don't want to use <- on the value x.
Now, it looks like you want to call print_matrix for each element of a list rather than a single element. In that case I think Macke is on the right track, but I would use mapM_ instead:
mapM_ (putStr . print_matrix . fst) x
should do the trick.
The reason is that you are explicitly saying you want to putStr each element, one at a time, but you don't care about the result of putStr itself.
It sounds like mapM might fit your bill: Monad a => (b -> a c) -> [b] -> a [c]
It's used to apply a monadic function to a list, and get a list back, in the monad

Resources