Haskell: Print case number - haskell

I have written a Haskell code as:
loop = do
x <- getLine
if x == "0"
then return ()
else do arr <- replicateM (read x :: Int) getLine
let blocks = map (read :: String -> Int) $ words $ unwords arr
putStr "Case X : output = "; -- <- What should X be?
print $ solve $ blockPair blocks;
loop
main = loop
This terminates at 0 input. I also want to print the case number eg. Case 1, 2 ...
Sample run:
1
10 20 30
Case 1: Output = ...
1
6 8 10
Case 2: Output = ...
0
Does anyone know how this can be done? Also, If possible can you suggest me a way to print the output line at the very end?
Thanks in advance.

For the first part of your question, the current case number is an example of some "state" that you want to maintain during the course of your program's execution. In other languages, you'd use a mutable variable, no doubt.
In Haskell, there are several ways to deal with state. One of the simplest (though it is sometimes a little ugly) is to pass the state explicitly as a function parameter, and this will work pretty well given the way you've already structured your code:
main = loop 1
loop n = do
...
putStr ("Case " ++ show n ++ ": Output = ...")
...
loop (n+1) -- update "state" for next loop
The second part of your question is a little more involved. It looks like you wanted a hint instead of a solution. To get you started, let me show you an example of a function that reads lines until the user enters end and then returns the list of all the lines up to but not including end (together with a main function that does something interesting with the lines using mostly pure code):
readToEnd :: IO [String]
readToEnd = do
line <- getLine
if line == "end"
then return []
else do
rest <- readToEnd
return (line:rest)
main = do
lines <- readToEnd
-- now "pure" code makes complex manipulations easy:
putStr $ unlines $
zipWith (\n line -> "Case " ++ show n ++ ": " ++ line)
[1..] lines
Edit: I guess you wanted a more direct answer instead of a hint, so the way you would adapt the above approach to reading a list of blocks would be to write something like:
readBlocks :: IO [[Int]]
readBlocks = do
n <- read <$> getLine
if n == 0 then return [] else do
arr <- replicateM n getLine
let block = map read $ words $ unwords arr
blocks <- readBlocks
return (block:blocks)
and then main would look like this:
main = do
blocks <- readBlocks
putStr $ unlines $
zipWith (\n line -> "Case " ++ show n ++ ": " ++ line)
[1..] (map (show . solve . blockPair) blocks)

This is similar in spirit to K. A. Buhr's answer (the crucial move is still passing state as a parameter), but factored differently to demonstrate a neat trick. Since IO actions are just normal Haskell values, you can use the loop to build the action which will print the output without executing it:
loop :: (Int, IO ()) -> IO ()
loop (nCase, prnAccum) = do
x <- getLine
if x == "0"
then prnAccum
else do inpLines <- replicateM (read x) getLine
let blocks = map read $ words $ unwords inpLines
prnAccumAndNext = do
prnAccum
putStr $ "Case " ++ show nCase ++ " : output = "
print $ solve $ blockPair blocks
loop (nCase + 1, prnAccumAndNext)
main = loop (1, return ())
Some remarks on the solution above:
prnAccum, the action which prints the results, is threaded through the recursive loop calls just like nCase (I packaged them both in a pair as a matter of style, but it would have worked just as fine if they were passed as separate arguments).
Note how the updated action, prnAccumAndNext, is not directly in the main do block; it is defined in a let block instead. That explains why it is not executed on each iteration, but only at the end of the loop, when the final prnAccum is executed.
As luqui suggests, I have removed the type annotations you used with read. The one at the replicateM call is certainly not necessary, and the other one isn't as well as long as blockPair takes a list of Int as an argument, as it seems to be the case.
Nitpicking: I removed the semicolons, as they are not necessary. Also, if arr refers to "array" it isn't a very appropriate name (as it is a list, and not an array), so I took the liberty to change it into something more descriptive. (You can find some other ideas for useful tricks and style adjustments in K. A. Buhr's answer.)

Related

How can I execute IO commands repeatedly in Haskell?

I have a function blabla in Haskell which takes an Int and returns a string:
blabla :: Int -> [Char]
I want to run that method repeatedly in a for-loop, something like this:
for i := 1 to 25 do begin
write(i);
write(": ");
writeln(blabla(i));
end;
Does haskell have a for loop feature?
There's a forM_ function in the Control.Monad module which is similar to a for loop in imperative programming languages:
import Control.Monad (forM_)
blabla :: Int -> String
blabla = show
main = forM_ [1..25] $ \i -> do
putStr (show i)
putStr ": "
putStrLn (blabla i)
However, I would advise you to stay away from such imperative style code. For example, the same code can be written more succinctly as:
import Control.Monad (mapM_)
blabla :: Int -> String
blabla = show
main = mapM_ (\i -> putStrLn $ show i ++ ": " ++ blabla i) [1..25]
Hope that helps.
Upon drinking a cup of tea I got the best result, I think:
blablaResults = map (\x -> show x ++ ":" ++ blabla x) [0..25]
main = putStrLn $ unlines blablaResults
You're still thinking in a procedural fashion. Try to think in terms of lists, rather than in terms of loops.
Then what you want is a list like this: [1,f(1),2,f(2),3,f(3)...,n,f(n)]
This is where map enters the picture. If you had a function f and wanted to apply it to a list [1,2,3...,n], you use map f [1..n].
What you want is a function that takes a number i and applies a function f to it,then responds with [i,f(i)] or perhaps a tuple (i,f(i)).
So you create this function and map it to your list.
And, of course, you need to create that initial list to operate on - that list from [1..n].
Another approach is to use a list comprehension:
forloop n = [(x,f x)|x <- [1..n] ]
(Note: I have no Haskell compiler with me right now, so I need to verify that last part later. I believe it should work as presented).
I think, I got it by myself:
blablaOutput :: [Int] -> IO()
blablaOutput (x:xs) = do
putStrLn (blabla x)
blablaOutput xs
blablaOutput _ = putStrLn "That's all, folks!"
main = blablaOutput [0..25]
Certainly not very functional in means of functional programming, but it works.

Trouble with type matching and IO in a recursive function

I'm experiencing some problems and can't find their reason. I am currently using the most recent version of GHCi portable - but to face the truth: It is my first time using Haskell, so as usual the problem is probably the user and not so much the system...
Problems that arise include:
I am not completely sure I got the difference between let x = 0 and x <- 0 right. I understand that let is to be used with pure functions, <- with side effects (IO)? Someone please explain that to me once again.
I have mismatchings between types, namely String and (String,[Char]) (and sometimes others...). The compiler tells me that String was expected, although I clearly defined the function as (String,String). What's going on? Did I somewhere make a mistake with the pattern matching?
The recursion does not work as expected (i.e. doesn't work at all apparently). If someone could help me with that, I would be very grateful.
Here's what I want to do:
I am trying to write a little program that implements a finite state machine accepting a word. That means it takes a set of states, one of which is the start state, a list of accepting states, and a number of transition rules. (The alphabets which represent the possible input and states are somewhat implicit.) I don't want to go into too much detail about FSMs here.
However, this is how I figured a way to define such a FSM could look:
"a(b+|c+)"
"start"
["b","c"]
[
("start", [('a',"a"), ('_',"reject")]),
("a", [ ('b',"b"), ('c',"c"), ('_',"reject")]),
("b", [ ('b',"b"), ('_',"reject")]),
("c", [ ('c',"c"), ('_',"reject")]),
("reject", [ ('_',"reject")])
]
In the first line, we have short description of what the FSM is supposed to accept (in form of a regex in this case). It is only used to display it once.
The second line defines the start state, the third line a list of accepting states.
All following lines together are the transition rules. In this example, if we are in state "start" and read an input 'a', the next state is "a", if we read anything else, it is "reject". (I am aware that I have not yet implemented the '_' meaning an else and the program will crash if an input is read for which no transition is defined.)
So here comes the program:
module FSM where
import System.IO
main :: IO ()
main = do
putStr "Enter file name: "
fileName <- getLine
(description, startState, acceptingStates, stateTransitions) <- (readDef fileName)
putStrLn ("FSM description: " ++ description)
putStr "Enter FSM input: "
input <- getLine
let input = reverse input
putStrLn "----------------"
let (finalState, oldStates) = changeState input startState stateTransitions
putStrLn (oldStates ++ finalState)
checkAcception finalState acceptingStates
--reads the specified .fsm file and returns
-- the description of the FSM (first line),
-- the start state (second line),
-- the list of accepting states (third line),
-- and the list of tuples containing all states and transitions (remaining lines)
readDef :: String -> IO (String, String, [String], [(String, [(Char,String)])])
readDef fileName = do
contents <- readFile (fileName ++ ".fsm")
let lineList = lines contents
let description = read (head lineList)
let startState = read (lineList !! 1)
let acceptingStates = read (lineList !! 2)
let stateTransitions = read (filter (/='\t') (concat (drop 3 lineList)))
return (description, startState, acceptingStates, stateTransitions)
--recursive function that takes the input, start state, and state transitions
--and computes the new state by a call to itself with the old state and a part of the input
changeState :: String -> String -> [(String, [(Char,String)])] -> (String, String)
changeState startState [] _ = (startState, "")
changeState startState (x:xs) stateTransitions = do
let (currentState, oldStates) = changeState xs startState stateTransitions
let newState = findKey x (findKey currentState stateTransitions)
let oldStates = (oldStates ++ currentState ++ " -(" ++ [x] ++ ")-> ")
return (newState, oldStates)
--helper function to find a key in a list of tuples and return the corresponding value
--(because we are not using the map notation in the .fsm file)
findKey :: (Eq k) => k -> [(k,v)] -> v
findKey key xs = snd . head . filter (\(k,v) -> key == k) $ xs
--checks for a given state whether or not it is in the list of accepting states
checkAcception :: String -> [String] -> IO ()
checkAcception finalState acceptingStates = do
let accept = any (==finalState) acceptingStates
if accept
then putStrLn "Input accepted!!"
else putStrLn "Input rejected!!"
The idea is to have the user choose a file from which the definition is loaded (readDef, works like a charm). He is then prompted to enter some input the FSM works on.
The recursive changeState then does the actual work (doesn't work as well...).
Finally, the sequence of states and transitions is displayed and it is checked whether the final state is an accepting state (checkAcceptance).
Now, don't try to optimize what I have written. I know, the way the definition is modeled can be improved and many of the lines I wrote can be written far shorter using some high order Haskell foo. But please just help me with the issues listed above (and of course help me make it work).
Thanks a lot in advance.
One last thing: I'm trying some Haskell for a seminar at my university, so if someone from the Software Architecture Group googled my code and reads this: Hi :)
You can get things to compile by just changing the second clause of the changeState function to:
changeState startState (x:xs) stateTransitions =
let (currentState, oldStates) = changeState xs startState stateTransitions
newState = findKey x (findKey currentState stateTransitions)
oldStates2 = (oldStates ++ currentState ++ " -(" ++ [x] ++ ")-> ")
in (newState, oldStates2)
We've 1) removed the do, 2) combined the let clauses and 3) renamed the second occurrence of the oldState variable to oldState2. In Haskell we don't redefine variables - we just create a variable with a new name. Complete code is available here: http://lpaste.net/118404
When you write:
(new, old) = changeState ...
you are saying that changeState is a pure function. If you define changeState with do ... return (...) you are saying it is a monadic computation and when you call it you need to use the arrow <- in a do block:
(new, old) <- changeState ...
Since changeState is a pure function (doesn't need to do IO) you might as well keep it as a pure function, so there is no reason to use do and return.
The problem is that do notation and the return function don't do what you think they do. In Haskell: return doesn't signify that a function should end (even though it's most commonly seen at the end of functions); it just means that the argument should be wrapped in a Monad. Because the type of your function with all arguments applied is (String,String) the compiler thought you were trying to use something like this: (won't actually compile without GHC extensions, and will throw exceptions if used because I used undefined)
instance Monad ((,) String) where
(>>=) = undefined :: (String,a) -> (a -> (String,b)) -> (String,b)
return = undefined :: a -> (String,a)
But the compiler already knew that (String,String) -> (String,String) doesn't match a -> (String,a) so it didn't get as far as checking whether or not the instance exists.
Fixing this problem revealed another one: you define oldStates twice in the same function, which doesn't work in Haskell unless the two definitions are in different scopes.
This is your function modified to compile properly, but I haven't tested it.
changeState :: String -> String -> [(String, [(Char,String)])] -> (String, String)
changeState startState [] _ = (startState, "")
changeState startState (x:xs) stateTransitions = let
(currentState, oldStates) = changeState xs startState stateTransitions
newState = findKey x (findKey currentState stateTransitions)
oldStates' = (oldStates ++ currentState ++ " -(" ++ [x] ++ ")-> ")
in (newState, oldStates')

Technique for reading in multiple lines for Haskell IO

Basically I would like to find a way so that a user can enter the number of test cases and then input their test cases. The program can then run those test cases and print out the results in the order that the test cases appear.
So basically I have main which reads in the number of test cases and inputs it into a function that will read from IO that many times. It looks like this:
main = getLine >>= \tst -> w (read :: String -> Int) tst [[]]
This is the method signature of w: w :: Int -> [[Int]]-> IO ()
So my plan is to read in the number of test cases and have w run a function which takes in each test case and store the result into the [[]] variable. So each list in the list will be an output. w will just run recursively until it reaches 0 and print out each list on a separate line. I'd like to know if there is a better way of doing this since I have to pass in an empty list into w, which seems extraneous.
As #bheklilr mentioned you can't update a value like [[]]. The standard functional approach is to pass an accumulator through a a set of recursive calls. In the following example the acc parameter to the loop function is this accumulator - it consists of all of the output collected so far. At the end of the loop we return it.
myTest :: Int -> [String]
myTest n = [ "output line " ++ show k ++ " for n = " ++ show n | k <- [1..n] ]
main = do
putStr "Enter number of test cases: "
ntests <- fmap read getLine :: IO Int
let loop k acc | k > ntests = return $ reverse acc
loop k acc = do
-- we're on the kth-iteration
putStr $ "Enter parameter for test case " ++ show k ++ ": "
a <- fmap read getLine :: IO Int
let output = myTest a -- run the test
loop (k+1) (output:acc)
allOutput <- loop 1 []
print allOutput
As you get more comfortable with this kind of pattern you'll recognize it as a fold (indeed a monadic fold since we're doing IO) and you can implement it with foldM.
Update: To help explain how fmap works, here are equivalent expressions written without using fmap:
With fmap: Without fmap:
n <- fmap read getLine :: IO [Int] line <- getLine
let n = read line :: Int
vals <- fmap (map read . words) getLine line <- getLine
:: IO [Int] let vals = (map read . words) line :: [Int]
Using fmap allows us to eliminate the intermediate variable line which we never reference again anyway. We still need to provide a type signature so read knows what to do.
The idiomatic way is to use replicateM:
runAllTests :: [[Int]] -> IO ()
runAllTests = {- ... -}
main = do
numTests <- readLn
tests <- replicateM numTests readLn
runAllTests tests
-- or:
-- main = readLn >>= flip replicateM readLn >>= runAllTests

Can I be sure of order of IO actions in this example?

At the moment, I have this code in and around main:
import Control.Monad
import Control.Applicative
binSearch :: Ord a => [a] -> a -> Maybe Int
main = do
xs <- lines <$> readFile "Cars1.txt"
x <- getLine <* putStr "Registration: " -- Right?
putStrLn $ case binSearch xs x of
Just n -> "Found at position " ++ show n
Nothing -> "Not found"
My hope is for “Registration: ” to be printed, then for the program to wait for the input to x. Does what I've written imply that that will be the case? Do I need the <*, or will putting the putStr expression on the line above make things work as well?
PS: I know I have to convert binSearch to work with arrays rather than lists (otherwise it's probably not worth doing a binary search), but that's a problem for another day.
The line
x <- getLine <* putStr "Registration: "
orders the IO actions left-to-right: first a line is taken as input, then the message is printed, and finally variable x is bound to the result of getLine.
Do I need the <*, or will putting the putStr expression on the line
above make things work as well?
If you want the message to precede the input, you have to put the putStr on the line above, as follows:
main :: IO ()
main = do
xs <- lines <$> readFile "Cars1.txt"
putStr "Registration: "
x <- getLine
putStrLn $ case binSearch xs x of
Just n -> "Found at position " ++ show n
Nothing -> "Not found"
Alternatively,
x <- putStr "Registration: " *> getLine
or
x <- putStr "Registration: " >> getLine
would work, but they are less readable.
Finally, since you added the lazy-evaluation tag, let me add that your question is actually not about laziness, but about how the operator <* is defined, and in particular about the order in which it sequences the IO actions.

Help In Solving Problem Using Guards - UPDATED With CODE

I am using guards inside a function but not immediately after the function signature. The guards are under a do statement inside the body of the function. I get this error:
parse error on input `|'
I thought maybe the error comes from the indentation but i have tried many indentation but still i get the errors. Am asking is it because the guards are not immedaitely after the function signature that is why am getting the errors?
thanks
UPDATE 1
CODE:
The user is suppose to guess a number , and the number will be compared with the random number if they are the same. If it is not correct then the user will guess till the "guess" variable in the function is zero. in every interation that value(guess) is decreased by one.
for instance : puzz 12 5. the user can guess for five times, the random number will be picked between 1 and 12. that is how the function is suppose to do, but it is not working.
puzz :: Int -> Int -> IO ()
puzz boundary guess = do
putStr "Guess"
-- putStr -- I have to print (1 .. guess) here in each iteration
putStr ":"
x <- randomRIO (1, boundary :: Int)
n <- getLine
let
nTo = read n::Int
in print x
| guess == 0 = putStr "You couldn't guess right,the correct answer is" ++ x
| nTo > x = putStr "lower"
| nTo < x = putStr "higer"
| nTo == x = putStr "Congrat, You guess right."
| otherwise raad boundary (guess - 1)
the ouput must be like this:
Main> puzz 50 6
Guess a number betwee 1 en 50.
Guess 1: 49
lower
Guess 2: 25
lower
Guess 3: 12
higher
Guess 4: 18
higher
Guess 5: 21
higher
Guess 6: 23
lower
You couldn't guess correct, the answer was: 22.
thanks for your help
You’re using guards incorrectly. From the report:
Top level patterns in case expressions and the set of top level patterns in function or pattern bindings may have zero or more associated guards.
So they’re only for cases and function bindings. If you just want to concisely introduce a series of true-false tests, while inside a do-notation, perhaps the case () of () trick would work:
main = do
putStrLn "hello world"
n <- getLine
let nTo = read n :: Int
case ()
of () | cond -> putStrLn "foo"
| cond' -> putStrLn "bar"
| otherwise -> putStrLn "baz"
It should be noted that there are several things that are a bit off with your code, in addition to using guards wrong. By default output is buffered in haskell so if you want Guess to be on the same line as input you have to either say that stdOut should not be buffered (hSetBuffering stdOut NoBuffering), or you have to flush output with hFlush. It's not necessary to write boundary :: Int, the compiler knows it is an Int. Here is a bit more complete example, I'm sure it could be done better but atleast it works:
import Control.Monad(liftM,unless)
import System.IO(hFlush,stdout)
import System.Random(randomRIO)
guessMyNumber upper guesses = do
putStrLn $ "Guess a number between 1 and " ++ show upper ++ "!"
randomRIO (1, upper) >>= puzz guesses
puzz 0 number = do
putStrLn $ "Sorry, no more guesses, the number was "
++ show number ++ "."
puzz guesses number = do
putStr "Guess:" >> hFlush stdout
guess <- liftM read getLine
printMessage guess number guesses
printMessage guess number guesses
| number > guess = putStrLn "higer" >> puzz (guesses-1) number
| number < guess = putStrLn "lower" >> puzz (guesses-1) number
| number == guess = putStrLn "Congratulations! You guessed right!"

Resources