Simple IO instructions on "read" command for new lisp user - io

I am a new lisp user. I have been trying to figure out how to use the lisp read command for about an hour by googling and looking for examples. I have been unsuccessful, and am finally throwing in the towel.
Can someone give me a very simple example of a lisp function that will accept 2 inputs, and add them?
My best attempt:
(defun func ()
(print "Enter first integer")
(read)
(print "Enter second integer")
(read)
(print (+ A B))
)
I have tried experimenting with (read A) or with a prefix to read (format t “~A” string) with no luck. All of the information on the internet that I have been looking for is extremely complicated, and I cannot make heads nor tails of it. Should it really be this hard? I may just be too familiar with bash/ksh/csh/sh...

You never assign the read input to your variables:
(defun func ()
(print "Enter first integer")
(finish-output)
(let ((a (read)))
(print "Enter second integer")
(finish-output)
(let ((b (read)))
(print (+ a b)))))

Related

Endless loop and a break for TUI in Haskell

I want to listen for keypresses and depending on those, use commands from System.Console.ANSI
package to manipulate console interface for my program.
In Python I would to this
while True:
read_from_console()
if condition:
print_stuff_into_console
break
How do I approach such task in Haskell, in simplest possible way?
Thanks
The equivalent abstract pseudo-ish code in Haskell would look like:
loop = do
line <- readFromConsole
if condition line
then do
printStuffToConsole
loop -- Recurse - i.e. repeat the same thing again
else
pure () -- Don't recurse - the function execution ends
main = loop
But of course the devil would be in how readFromConsole and printStuffToConsole look. And these really depend on what exactly you'd like to do.
I will offer the dumbest possible implementation, just to illustrate how everything works and to build a complete program.
Let's say that "read from console" just means having the user enter a line of text and press Enter. For that, you can use the getLine function:
readFromConsole = getLine
And let's say you want to print the same thing every time. For printing, you can use the putStrLn function:
printStuffToConsole = putStrLn "Give me another!"
And then let's say that the condition for stopping is that the user enters "STOP". This can be expressed with a string comparison:
condition line = line /= "STOP"
If you put all of that together, you get a complete program:
loop = do
line <- readFromConsole
if condition line
then do
printStuffToConsole
loop -- Recurse - i.e. repeat the same thing again
else
pure () -- Don't recurse - the function execution ends
where
readFromConsole = getLine
printStuffToConsole = putStrLn "Give me another!"
condition line = line /= "STOP"
main = loop
Of course, while it's nice to have parts of the program semantically named, you don't strictly speaking have to do it if you wanted to make the whole thing shorter:
main = do
line <- getLine
if line /= "STOP"
then do
putStrLn "Give me another!"
main
else
pure ()
Fyodor Soikin already provided the simple way to do it.
Here I'll comment on a general way to "break" a loop: using continuations and callCC.
import Control.Monad.Cont
main :: IO ()
main = do
putStrLn "start"
flip runContT return $ callCC $ \break -> forever $ do
l <- lift $ getLine
if l == "quit"
then break ()
else lift $ putStrLn $ "not a quit command " ++ l
lift $ putStrLn "next iteration"
putStrLn "end"
Continuations are infamously hard to grasp, but the above code is not too complex. A rough intuition is as follows.
The forever library function is used to repeat an action indefinitely, it is the Haskell equivalent of while true.
The flip runContT return $ callCC $ \f -> .... part means "define f to be a break-like function, which will exit the "block" .... immediately. In the code, I call that break to make that clear. The call break () interrupts the forever (and returns the () outside -- we could use that value if we wrote x <- flip runContT .... to bind it to x).
There is a downside, though. In the .... part we no longer work inside the IO monad, but in the ContT () IO monad. That is what lets us call break (). In order to use regular IO there, we need to lift the IO actions. So, we can't use putStrLn ".." but we need to use lift $ putStrLn ".." instead.
The rest should be more or less straightforward to follow.
Here's a small demo in GHCi.
> main
start
1 (typed by the user)
not a quit command 1
next iteration
2 (typed by the user)
not a quit command 2
next iteration
3 (typed by the user)
not a quit command 3
next iteration
4 (typed by the user)
not a quit command 4
next iteration
quit (typed by the user)
end
Is it a good idea to use continuation just for break? Maybe. If you are not familiar with this technique, probably it is not worth it. The plain recursive approach looks much simpler.

Breaking out of monad sequence

Is it possible to break out of a monad sequence?
For instance, if I want to break out of a sequence earlier based on some condition calculated in the middle of the sequence. Say, in a 'do' notation I bind a value and based on the value I want to either finish the sequence or stop it. Is there something like a 'pass' function?
Thanks.
Directly using if
You could do this directly as Ingo beautifully encapsulated, or equivalently for example
breakOut :: a -> m (Either MyErrorType MyGoodResultType)
breakOut x = do
y <- dosomethingWith x
z <- doSomethingElseWith x y
if isNoGood z then return (Left (someerror z)) else do
w <- process z
v <- munge x y z
u <- fiddleWith w v
return (Right (greatResultsFrom u z))
This is good for simply doing something different based on what values you have.
Using Exceptions in the IO monad
You could use Control.Exception as Michael Litchard correctly pointed out. It has tons of error-handling, control-flow altering stuff in it, and is worth reading if you want to do something complex with this.
This is great if your error production could happen anywhere and your code is complex. You can handle the errors at the top level, or at any level you like. It's very flexible and doesn't mess with your return types. It only works in the IO monad.
import Control.Exception
Really I should roll my own custom type, but I can't be bothered deriving Typable etc, so I'll hack it with the standard error function and a few strings. I feel quite guilty about that.
handleError :: ErrorCall -> IO Int
handleError (ErrorCall msg) = case msg of
"TooBig" -> putStrLn "Error: argument was too big" >> return 10000
"TooSmall" -> putStrLn "Error: argument was too big" >> return 1
"Negative" -> putStrLn "Error: argument was too big" >> return (-1)
"Weird" -> putStrLn "Error: erm, dunno what happened there, sorry." >> return 0
The error handler needs an explicit type to be used in catch. I've flipped the argument to make the do block come last.
exceptOut :: IO Int
exceptOut = flip catch handleError $ do
x <- readLn
if (x < 5) then error "TooSmall" else return ()
y <- readLn
return (50 + x + y)
Monad transformers etc
These are designed to work with any monad, not just IO. They have the same benefits as IO's exceptions, so are officially great, but you need to learn about monad tranformers. Use them if your monad is not IO, and you have complex requirements like I said for Control.Exception.
First, read Gabriel Conzalez's Breaking from a loop for using EitherT to do two different things depending on some condition arising, or MaybeT for just stopping right there in the event of a problem.
If you don't know anything about Monad Transformers, you can start with Martin Grabmüller's Monad Transformers Step by Step. It covers ErrorT. After that read Breaking from a Loop again!
You might also want to read Real World Haskell chapter 19, Error handling.
Call/CC
Continuation Passing Style's callCC is remarkably powerful, but perhaps too powerful, and certainly doesn't produce terribly easy-to-follow code. See this for a fairly positive take, and this for a very negative one.
So what I think you're looking for is the equivalent of return in imperative languages, eg
def do_something
foo
bar
return baz if quux
...
end
Now in haskell this is doesn't work because a monadic chain is just one big function application. We have syntax that makes it look prettier but it could be written as
bind foo (bind bar (bind baz ...)))
and we can't just "stop" applying stuff in the middle. Luckily if you really need it there is an answer from the Cont monad. callCC. This is short for "call with current continuation" and generalizes the notation of returns. If you know Scheme, than this should be familiar.
import Control.Monad.Cont
foo = callCC $ \escape -> do
foo
bar
when baz $ quux >>= escape
...
A runnable example shamelessly stolen from the documentation of Control.Monad.Cont
whatsYourName name =
(`runCont` id) $ do
response <- callCC $ \exit -> do
validateName name exit
return $ "Welcome, " ++ name ++ "!"
return response
validateName name exit = do
when (null name) (exit "You forgot to tell me your name!")
and of course, there is a Cont transformer, ContT (which is absolutely mind bending) that will let you layer this on IO or whatever.
As a sidenote, callCC is a plain old function and completely nonmagical, implementing it is a great challenge
So I suppose there is no way of doing it the way I imagined it originally, which is equivalent of a break function in an imperative loop.
But I still get the same effect below based in Ingo's answer, which is pretty easy (silly me)
doStuff x = if x > 5
then do
t <- getTingFromOutside
doHeavyHalculations t
else return ()
I don't know though how it would work if I need to test 't' in the example above ...
I mean, if I need to test the bound value and make an if decision from there.
You can never break out of a "monad sequence", by definition. Remember that a "monad sequence" is nothing else than one function applied to other values/functions. Even if a "monad sequence" gives you the illusion that you could programme imperative, this is not true (in Haskell)!
The only thing you can do is to return (). This solution of the practical problem has already been named in here. But remember: it gives you only the illusion of being able to break out of the monad!

How to keep track of number of guesses in a simple guessing game (Haskell)

I've been attempting to learn Haskell independently in the last few weeks. Currently, I'm trying to implement a goofy little guessing game where the computer chooses a random number and the user tries to guess it. If the user is wrong, the program tells the user either that the answer is higher or lower and allows the user to guess until they guess correctly. I've got it working, but I would like to add the ability to keep track of the number of guesses that the user makes every game and report that number to the user once they guess correctly.
Coming from an imperative background, the natural thing to do would be to have a counter that is incremented every time the user makes a guess, but you can't really do that in Haskell (at least it seems like the statelessness and immutability of everything would prevent that).
I toyed with the idea of making the getGuess and giveHints functions take an extra parameter that represents the number of guesses so far (let's call it numGuesses), and, on every call to those methods, pass (numGuesses+1). But I couldn't get that to work (not to mention I don't even know if that would work).
My code is below. Any suggestions would be really appreciated. I'm mostly looking for ideas, but feel free to post actual code as well. Also, feel free to let me know if my code sucks and how I could improve it if you notice anything heinous (I've only been programming functionally for a couple weeks!)
import System.Random
import System.IO
import Control.Monad
main = do
gen <- getStdGen
let (ans,_) = randomR (1,100) gen :: (Int,StdGen)
putStrLn $ "I'm thinking of a number between 1 and 100..."
getGuess ans
putStrLn "You guessed it in __ guesses!"
putStr "Play again? "
hFlush stdout
desire <- getLine
when ((desire !! 0) `elem` ['y','Y']) $ do
putStrLn ""
newStdGen
main
getGuess ans = do
putStr "Your guess? "
hFlush stdout
guessStr <- getLine
giveHints ans (read guessStr)
giveHints ans guess = do
when (ans /= guess) $ do
if ans > guess
then putStrLn "It's higher."
else putStrLn "It's lower."
getGuess ans
Note: I am using hFlush stdout because I'm using line buffering and, without it, the order of some of the interactions are not what one would expect.
You can in fact implement the counting method you were thinking about, but you still have to pass the state around explicitly. But in this case, it isn't much of a hassle at all. In fact, this is a pattern that one sees pretty often for helper functions, where actually using the State monad would be overkill.
The pattern I'm referring to often looks like this:
doStuff xs' = go xs' 0
where
go (x:xs) n = .. etc ..
Here's the code.
import System.Random (randomRIO)
import Control.Applicative ((<$>))
import Control.Monad (when)
import Text.Printf (printf)
playGame :: Int -> Int -> IO ()
playGame answer curGuesses = do
putStrLn "What is your guess?"
putStr ">"
guess <- getGuessFromUser
when (guess /= answer) $ do
giveHints answer guess
playGame answer (curGuesses + 1)
when (guess == answer) $ do
putStrLn "You guessed it!"
printf "You guessed %d times!\n" (curGuesses + 1)
giveHints :: Int -> Int -> IO ()
giveHints answer guess
| answer > guess = putStrLn "It's higher!"
| otherwise = putStrLn "It's lower!"
getGuessFromUser :: IO Int
getGuessFromUser = do
read <$> getLine
main :: IO ()
main = do
answer <- randomRIO (1, 100)
putStrLn "I'm thinking of a number between 1 and 100."
playGame answer 0
Notes
<$> is fmap
I used randomRIO as Daniel mentioned, since we're already in the IO monad.
I did not have to use hSetBuffering or hFlush using the command prompt on Windows to get correct output. YMMV, however.
Adding an extra parameter for the number of guesses is exactly how you do this sort of thing functionally.
The basic functional mode of thinking is that if you have a function that needs to behave differently depending on different values of "something", then that something is a parameter to the function. This is a simple consequence of purity; a function must always return the same thing for the same inputs.
When you get to more advanced techniques there are various ways of "hiding" the extra parameters to free you up from having to write/pass them explicitly; this is basically exactly what the State monad does, and one way of thinking about the IO monad is that it's doing something similar. But while you're new to functional programming it's probably more helpful to get used to this mode of thinking; you communicate information to a function you're calling through its arguments, and receive information back through its arguments. You can't resort to the imperative trick of just leaving information in some external place (e.g. the value of a counter) where you know the function you call will look for it (or even modify it).

Haskell case statement

I have code something like this
main :: [[String]] -> IO ()
main st = do
answer <- getLine
case answer of
"q" -> return ()
"load" x -> main $ parseCSV $ readFile x
This doesn't work, so my question is how can I use case switch statement for something of changing input
For example in my code I want the input from a user to be either q or a load, but the load will constant change:
load "sample.csv"
load "test.csv"
load "helloworld.csv"
In my code I indicated the constantly changing input as X, but this doesn't work as I expected it.
Help would be appreciated, thank you.
As others have mentioned, the problem is with your pattern matching.
Here's a simple way to get around this (and still have something readable).
Split answer into words for matching (with the words function).
Use the first word in the pattern match.
If you want to use the remaining "words", simply unwords the remaining elems in the list to get a string.
Example:
main :: IO ()
main = do
answer <- getLine
case words answer of
("q":_) -> putStrLn "I'm quitting!"
("load":x) -> putStrLn ("Now I will load " ++ unwords x)
otherwise -> putStrLn "Not sure what you want me to do!"
Note - the x you had above is actually unwords x here.

Good Haskell coding style of if/else control block?

I'm learning Haskell in the hope that it will help me get closer to functional programming. Previously, I've mostly used languages with C-like syntax, like C, Java, and D.
I have a little question about the coding style of an if/else control block used by the tutorial on Wikibooks. The code looks like the following:
doGuessing num = do
putStrLn "Enter your guess:"
guess <- getLine
if (read guess) < num
then do putStrLn "Too low!"
doGuessing num
else if (read guess) > num
then do putStrLn "Too high!"
doGuessing num
else do putStrLn "You Win!"
It makes me confused, because this coding style totally violates the recommended style in C-like languages, where we should indent if, else if, and else at the same column.
I know it just does not work in Haskell, because it would be a parse error if I indented else at the same column as if.
But what about the following style? I think it is much more clear than the above one. But since the above is used by Wikibooks and Yet Another Haskell Tutorial, which is marked "best tutorial available online" at the official Haskell website, I'm not sure whether this coding style is a convention in Haskell programs.
doGuessing num = do
putStrLn "Enter your guess:"
guess <- getLine
if (read guess) < num then
do
putStrLn "Too low!"
doGuessing num
else if (read guess) > num then do
putStrLn "Too high!"
doGuessing num
else do
putStrLn "You Win!"
So, I'm curious about which coding style is used more often—or is there another coding style for this piece of code?
Haskell style is functional, not imperative! Rather than "do this then that," think about combining functions and describing what your program will do, not how.
In the game, your program asks the user for a guess. A correct guess is a winner. Otherwise, the user tries again. The game continues until the user guesses correctly, so we write that:
main = untilM (isCorrect 42) (read `liftM` getLine)
This uses a combinator that repeatedly runs an action (getLine pulls a line of input and read converts that string to an integer in this case) and checks its result:
untilM :: Monad m => (a -> m Bool) -> m a -> m ()
untilM p a = do
x <- a
done <- p x
if done
then return ()
else untilM p a
The predicate (partially applied in main) checks the guess against the correct value and responds accordingly:
isCorrect :: Int -> Int -> IO Bool
isCorrect num guess =
case compare num guess of
EQ -> putStrLn "You Win!" >> return True
LT -> putStrLn "Too high!" >> return False
GT -> putStrLn "Too low!" >> return False
The action to be run until the player guesses correctly is
read `liftM` getLine
Why not keep it simple and just compose the two functions?
*Main> :type read . getLine
<interactive>:1:7:
Couldn't match expected type `a -> String'
against inferred type `IO String'
In the second argument of `(.)', namely `getLine'
In the expression: read . getLine
The type of getLine is IO String, but read wants a pure String.
The function liftM from Control.Monad takes a pure function and “lifts” it into a monad. The type of the expression tells us a great deal about what it does:
*Main> :type read `liftM` getLine
read `liftM` getLine :: (Read a) => IO a
It's an I/O action that when run gives us back a value converted with read, an Int in our case. Recall that readLine is an I/O action that yields String values, so you can think of liftM as allowing us to apply read “inside” the IO monad.
Sample game:
1
Too low!
100
Too high!
42
You Win!
You can use the "case"-construct:
doGuessing num = do
putStrLn "Enter your guess:"
guess <- getLine
case (read guess) of
g | g < num -> do
putStrLn "Too low!"
doGuessing num
g | g > num -> do
putStrLn "Too high!"
doGuessing num
otherwise -> do
putStrLn "You Win!"
A minor improvement to mattiast's case statement (I'd edit, but I lack the karma) is to use the compare function, which returns one of three values, LT, GT, or EQ:
doGuessing num = do
putStrLn "Enter your guess:"
guess <- getLine
case (read guess) `compare` num of
LT -> do putStrLn "Too low!"
doGuessing num
GT -> do putStrLn "Too high!"
doGuessing num
EQ -> putStrLn "You Win!"
I really like these Haskell questions, and I'd encourage others to post more. Often you feel like there's got to be a better way to express what you're thinking, but Haskell is initially so foreign that nothing will come to mind.
Bonus question for the Haskell journyman: what's the type of doGuessing?
The way Haskell interprets if ... then ... else within a do block is very much in keeping with the whole of Haskell's syntax.
But many people prefer a slightly different syntax, permitting then and else to appear at the same indentation level as the corresponding if. Therefore, GHC comes with an opt-in language extension called DoAndIfThenElse, which permits this syntax.
The DoAndIfThenElse extension is made into part of the core language in the latest revision of the Haskell specification, Haskell 2010.
Note that the fact that you have to indent the 'then' and 'else' inside a 'do' block is considered a bug by many. It will probably be fixed in Haskell' (Haskell prime), the next version of the Haskell specification.
You can also use explicit grouping with curly braces. See the layout section of http://www.haskell.org/tutorial/patterns.html
I wouldn't recommend that though. I've never seen anyone use explicit grouping besides in a few special cases. I usually look at the Standard Prelude code for examples of style.
I use a coding style like your example from Wikibooks. Sure, it doesn't follow the C guidelines, but Haskell's not C, and it's fairly readable, especially once you get used to it. It's also patterned after the style of algorithms used in many textbooks, like Cormen.
You will see a bunch of different indentation styles for Haskell. Most of them are very hard to maintain without an editor that is set up to indent exactly in whatever style.
The style you display is much simpler and less demanding of the editor, and I think you should stick with it. The only inconsistency I can see is that you put the first do on its own line while you put the other dos after the then/else.
Heed the other advice about how to think about code in Haskell, but stick to your indentation style.

Resources