getLine and is value integer - haskell

I get value using x <- getLine, how can I check that x can be interpreted as an integer number?

do x <- getLine
case filter (\(_,s) -> s == "") (reads x :: [(Int, String)]) of
[] -> putStrLn "x cannot be parsed as an Int"
(xAsInt, _) : _
-> putStrLn (concat ["x can be parsed as an Int, *and* its Int value is ",
show xAsInt])

Look into Data.Char.isNumber.

Haskell: Check if integer, or check type of variable

You could create a maybeIO function that performs an IO action in a catch, returning Just the result of the action if successful, or Nothing if an exception occurred. Then, you can use readLn instead of getLine + reads, with maybeIO to convert any exception into a Nothing.
import Control.Monad (liftM)
maybeIO :: IO a -> IO (Maybe a)
maybeIO f = catch (liftM Just f) (const $ return Nothing)
main = do
i <- maybeIO (readLn :: IO Int)
print i

Related

Haskell get values from IO domain

After reading the Haskell books I am kind of confused (or I simply forgot) how to get a value from the IO domain, into the 'Haskell world' to parse it, like so:
fGetSeq = do
input <- sequence [getLine, getLine, getLine]
fTest input
mapM_ print input
fTest = map (read :: String -> Int)
Obviously compiler complains. Couldn't match [] with IO. Is there a simple rule of thumb for passing values between 'worlds' or is it just my bad by omitting typesigs?
The thing about do notation is, every monadic action value in it (those to the right of <-s, or on their own line) must belong to the same monad. It's
do {
x <- ma ; -- ma :: m a x :: a
y <- mb ; -- mb :: m b y :: b ( with the same m! )
return (foo x y) -- foo x y :: c return (foo x y) :: m c
} -- :: m c
Now, since sequence [getLine, getLine, getLine] :: IO [String], this means your do block belongs in IO.
But you can treat the values in their own right, when you got them:
fGetSeq :: IO ()
fGetSeq = do
inputs <- sequence [getLine, getLine, getLine] -- inputs :: [String]
let vals = fTest inputs
mapM_ print vals
fTest :: [String] -> [Int]
fTest = map (read :: String -> Int)
-- or just
fGetSeq1 = do
inputs <- sequence [getLine, getLine, getLine]
mapM_ print ( fTest inputs )
-- or
fGetSeq2 = do { vals <- fTest <$> sequence [getLine, getLine, getLine] ;
mapM_ print vals } -- vals :: [Int]
-- or even (with redundant parens for clarity)
fGetSeq3 = mapM_ print =<< ( fTest <$> sequence [getLine, getLine, getLine] )
-- = mapM_ print . fTest =<< sequence [getLine, getLine, getLine]
The essence of Monad is the layering of the pure 'Haskell world' calculations in between the potentially impure, 'effectful' computations.
So we already are in the pure Haskell world, on the left hand side of that <-. Again, inputs :: [String]. A pure value.
get a value from the IO domain, into the 'Haskell world'
You use the bind operator: (>>=) :: Monad m => m a -> (a -> m b) -> m b.
If m = IO it looks like: (>>=) :: IO a -> (a -> IO b) -> IO b.
As you can see, the function with type a -> IO b addresses the a without IO.
So given a value in the IO monad, e.g. getLine :: IO String:
getInt :: IO Int
getInt = getLine >>= (\s -> return (read s))
Here, s :: String, read :: String -> Int, and return :: Int -> IO Int.
You can rewrite this using a do-block:
getInt :: IO Int
getInt = do
s <- getLine
return (read s)
Or use the standard library function that does exactly this:
getInt :: IO Int
getInt = readLn
As for your example, you can immediately fix it using a let-binding:
foo :: IO ()
foo = do
input <- sequence [getLine, getLine, getLine]
let ints = bar input
mapM_ print ints
bar :: [String] -> [Int]
bar = map read
Or you can restructure it to use getInt as defined above:
foo :: IO ()
foo = sequence [getInt, getInt, getInt] >>= mapM_ print

combining StateT with InputT

It is a follow-up to this question. I'm trying to combine shell from #ErikR's answer in my InputT loop.
main :: IO [String]
main = do
c <- makeCounter
execStateT (repl c) []
repl :: Counter -> StateT [String] IO ()
repl c = lift $ runInputT defaultSettings loop
where
loop = do
minput <- getLineIO $ in_ps1 $ c
case minput of
Nothing -> lift $ outputStrLn "Goodbye."
Just input -> (liftIO $ process c input) >> loop
getLineIO :: (MonadException m) => IO String -> InputT m (Maybe String)
getLineIO ios = do
s <- liftIO ios
getInputLine s
And getting an error
Main.hs:59:10:
Couldn't match type ‘InputT m0’ with ‘IO’
Expected type: StateT [String] IO ()
Actual type: StateT [String] (InputT m0) ()
Relevant bindings include
loop :: InputT (InputT m0) () (bound at Main.hs:61:3)
In the expression: lift $ runInputT defaultSettings loop
In an equation for ‘repl’:
repl c
= lift $ runInputT defaultSettings loop
where
loop
= do { minput <- getLineIO $ in_ps1 $ c;
.... }
Main.hs:62:5:
No instance for (Monad m0) arising from a do statement
The type variable ‘m0’ is ambiguous
Relevant bindings include
loop :: InputT (InputT m0) () (bound at Main.hs:61:3)
Note: there are several potential instances:
instance Monad (Text.Parsec.Prim.ParsecT s u m)
-- Defined in ‘Text.Parsec.Prim’
instance Monad (Either e) -- Defined in ‘Data.Either’
instance Monad Data.Proxy.Proxy -- Defined in ‘Data.Proxy’
...plus 15 others
In a stmt of a 'do' block: minput <- getLineIO $ in_ps1 $ c
In the expression:
do { minput <- getLineIO $ in_ps1 $ c;
case minput of {
Nothing -> lift $ outputStrLn "Goodbye."
Just input -> (liftIO $ process c input) >> loop } }
In an equation for ‘loop’:
loop
= do { minput <- getLineIO $ in_ps1 $ c;
case minput of {
Nothing -> lift $ outputStrLn "Goodbye."
Just input -> (liftIO $ process c input) >> loop } }
The full code can be found here, it's based on Write you a haskell.
I know haskelline has a built-in support for history, but I'm trying to implement it myself as an exercise.
Feel free to suggest replacements for the monad transformers to get the same functionality.
My Real Problem
I'd like to add ipython like capabilities to the lambda REPL in Write You a Haskell, namely:
I. A counter for input and output, that will appear in the prompt, i.e
In[1]>
Out[1]>
This is already done.
II. Save each command to history (automatically), and display all previous commands using a special command, e.g. histInput (same as hist in ipython). Also, save a history of all output results and display them using histOutput. This is what I'm trying to do in this question (input history only for the moment).
III. Reference previous inputs and outputs, e.g. if In[1] was x, then In[1] + 2 should be substituted by x + 2, and likewise for the output.
Update
I've tried to combine #ErikR's answer, and temporarily disabled showStep, coming up with:
module Main where
import Syntax
import Parser
import Eval
import Pretty
import Counter
import Control.Monad
import Control.Monad.Trans
import System.Console.Haskeline
import Control.Monad.State
showStep :: (Int, Expr) -> IO ()
showStep (d, x) = putStrLn ((replicate d ' ') ++ "=> " ++ ppexpr x)
process :: Counter -> String -> InputT (StateT [String] IO) ()
process c line =
if ((length line) > 0)
then
if (head line) /= '%'
then do
modify (++ [line])
let res = parseExpr line
case res of
Left err -> outputStrLn $ show err
Right ex -> do
let (out, ~steps) = runEval ex
--mapM_ showStep steps
out_ps1 c $ out2iout $ show out
else do
let iout = handle_cmd line
out_ps1 c iout
-- TODO: don't increment counter for empty lines
else do
outputStrLn ""
out2iout :: String -> IO String
out2iout s = return s
out_ps1 :: Counter -> IO String -> InputT (StateT [String] IO) ()
out_ps1 c iout = do
out <- liftIO iout
let out_count = c 0
outputStrLn $ "Out[" ++ (show out_count) ++ "]: " ++ out
outputStrLn ""
handle_cmd :: String -> IO String
handle_cmd line = if line == "%hist"
then
evalStateT getHist []
else
return "unknown cmd"
getHist :: StateT [String] IO String
getHist = do
hist <- lift get
forM_ (zip [(1::Int)..] hist) $ \(i, h) -> do
show i ++ ": " ++ show h
main :: IO ()
main = do
c <- makeCounter
repl c
repl :: Counter -> IO ()
repl c = evalStateT (runInputT defaultSettings(loop c)) []
loop :: Counter -> InputT (StateT [String] IO) ()
loop c = do
minput <- getLineIO $ in_ps1 $ c
case minput of
Nothing -> return ()
Just input -> process c input >> loop c
getLineIO :: (MonadException m) => IO String -> InputT m (Maybe String)
getLineIO ios = do
s <- liftIO ios
getInputLine s
in_ps1 :: Counter -> IO String
in_ps1 c = do
let ion = c 1
n <- ion
let s = "Untyped: In[" ++ (show n) ++ "]> "
return s
which still doesn't compile:
Main.hs:59:5:
Couldn't match type ‘[]’ with ‘StateT [String] IO’
Expected type: StateT [String] IO String
Actual type: [()]
In a stmt of a 'do' block:
forM_ (zip [(1 :: Int) .. ] hist)
$ \ (i, h) -> do { show i ++ ": " ++ show h }
In the expression:
do { hist <- lift get;
forM_ (zip [(1 :: Int) .. ] hist) $ \ (i, h) -> do { ... } }
In an equation for ‘getHist’:
getHist
= do { hist <- lift get;
forM_ (zip [(1 :: Int) .. ] hist) $ \ (i, h) -> ... }
I'm going to take a guess at what you are trying to do.
This program recognizes the following commands:
hist -- show current history
add xxx -- add xxx to the history list
clear -- clear the history list
count -- show the count of history items
quit -- quit the command loop
Program source:
import System.Console.Haskeline
import Control.Monad.Trans.Class
import Control.Monad.Trans.State.Strict
import Control.Monad
main :: IO ()
main = evalStateT (runInputT defaultSettings loop) []
loop :: InputT (StateT [String] IO) ()
loop = do
minput <- getInputLine "% "
case minput of
Nothing -> return ()
Just "quit" -> return ()
Just input -> process input >> loop
process input = do
let args = words input
case args of
[] -> return ()
("hist": _) -> showHistory
("add" : x : _) -> lift $ modify (++ [x])
("clear": _) -> lift $ modify (const [])
("count": _) -> do hs <- lift get
outputStrLn $ "number of history items: " ++ show (length hs)
_ -> outputStrLn "???"
showHistory = do
hist <- lift get
forM_ (zip [(1::Int)..] hist) $ \(i,h) -> do
outputStrLn $ show i ++ " " ++ h
The first error is because you have declared
main :: IO ()
but also
execStateT (...) :: IO [String]
execStateT returns the computation's final state, and your state is of type [String]. Usually this is fixed by just not declaring a type for main and letting it be inferred to be IO a for some a. The second one I'm not sure about, but maybe it's the same thing.
The code you have here compiles, and it defines process as:
process :: Counter -> String -> IO ()
To create a version of process with this signature:
Counter -> String -> InputT (StateT [String] IO) ()
just use liftIO:
process' :: Counter -> String -> InputT (StateT [String] IO) ()
process' counter str = liftIO $ process counter str

How to set getLine to only receive strings that can be converted to numbers?

main = do
putStrLn "Hello,Name please?"
first <- getLine
second <- getLine
third <- getLine
if (second == "divide") then putStrLn (show (read first ::Double )/ (read third :: Double))
else putStrLn "Cannot do"
So i want a number in first and third variables,and the second variable will be given the work divide and the if statement will begin and convert the String in first to a Double.But i think the issue is that the variable First is expecting a String like "one" that cannot be converted to a Double.How to fix this to allow getLine to only receive Strings that can be changed in numbers
Here's a quick idea that could help you:
import Control.Applicative
import Data.Char
getNum :: (Num a, Read a) => IO (Maybe a)
getNum = do
(x, xs) <- break (not . isDigit ) <$> getLine
case xs of
[] -> return $ Just $ read x
_ -> return Nothing
main :: IO ()
main = do
x <- getNum :: IO (Maybe Double)
case x of
Nothing -> do
putStrLn "Not a number, try again"
main
Just x' ->
putStrLn $ "Your number: " ++ show x'
return ()
You cannot "make" getLine accept only numbers, you make a function that does. You can even modify this function to accept only the first set of numbers before a non-digit (right now it returns Nothing if any non-digit is in the string).
Update
Here's a program that asks for two numbers and an operation, doing some value checking:
import Control.Applicative
import Data.Char
import Data.Maybe
getNum :: (Num a, Read a) => IO (Maybe a)
getNum = do
(x, xs) <- break (not . isDigit ) <$> getLine
case xs of
[] -> return $ Just $ read x
_ -> return Nothing
main :: IO ()
main = do
putStr "First: "
x <- getNum :: IO (Maybe Double)
putStr "Operation: "
op <- getLine
putStr "Second: "
y <- getNum :: IO (Maybe Double)
if isJust x && isJust y then do
let
x' = fromJust x
y' = fromJust y
putStr "Result: "
case op of
"divide" -> putStrLn $ show $ x' / y'
"sum" -> putStrLn $ show $ x' + y'
_ -> putStrLn "No operation"
else
putStrLn "Invalid numbers"
return ()

Looping over a monadic predicate

For looping over a function until a predicate holds there is
until :: (a -> Bool) -> (a -> a) -> a -> a
Yet, this falls short once the predicate has the form
Monad m => (a -> m b)
The only way I found out of this is via explicit recursion, e.g. when reading from a handle until EOF is reached:
(_, (Just stdout), _, _) <- createProcess (proc "task" (args fl)){ std_out = CreatePipe }
let readH :: IO [Either String Task] -> IO [Either String Task]
readH l = do eof <- hIsEOF stdout
if eof
then l
else do line <- hGetLine stdout
l' <- l
readH.return $ (eitherDecodeStrict' line) : l'
out <- readH $ return []
Is there a higher order function that simplifies this? Maybe together with sequence?
You can define a "monadic until" function yourself, for example
untilM :: Monad m => (a -> m Bool) -> (a -> m a) -> a -> m a
untilM p f = go
where
go x = do r <- p x
if r
then return x
else do a <- f x
go a
or perhaps, if your predicate doesn't need an argument,
untilM :: Monad m => m Bool -> (a -> m a) -> a -> m a
untilM p f = go
where
go x = do r <- p
if r
then return x
else do a <- f x
go a
or even, you don't want any arguments at all,
untilM :: Monad m => m Bool -> m a -> m ()
untilM p f = do r <- p
if r
then return ()
else do f
untilM p f
Let's refactor your code until we arrive at such a combinator.
let readH :: IO [Either String Task] -> IO [Either String Task]
readH l = do eof <- hIsEOF stdout
if eof
then l
else do line <- hGetLine stdout
l' <- l
readH.return $ (eitherDecodeStrict' line) : l'
out <- readH $ return []
First I want to point out the superfluous returns. In this code you never call readH without an accompanying return. The argument to readH can actually be pure by simply removing the unnecessary returns. Notice that we had to add return l on the then branch, and no longer have to "perform" l' <- l on the else branch.
let readH :: [Either String Task] -> IO [Either String Task]
readH l = do eof <- hIsEOF stdout
if eof
then return l
else do line <- hGetLine stdout
readH $ (eitherDecodeStrict' line) : l
out <- readH []
Okay, now I'm going to rename a few things for clarity and slightly reformat.
let -- how to check the stop condition
condition :: IO Bool
condition = hIsEOF stdout
let -- what IO to do at each iteration
takeOneStep :: IO ByteString
takeOneStep = hGetLine stdout
let -- what pure work to do at each iteration
pureTransform :: ByteString -> Either String Task
pureTransform = eitherDecodeStrict'
let readH :: [Either String Task] -> IO [Either String Task]
readH theRest = do
isDone <- condition
if isDone
then return theRest
else do
raw <- takeOneStep
readH (pureTransform raw : theRest)
out <- readH []
Make sure you understand how this version of the code is the same as the last version; it just has a few expressions renamed and factored out.
pureTransform is a bit of a red herring here. We can bundle it with takeOneStep instead.
let -- how to check the stop condition
condition :: IO Bool
condition = hIsEOF stdout
let -- what IO to do at each iteration
takeOneStep :: IO (Eiter String Task)
takeOneStep = do
line <- hGetLine stdout
return (eitherDecodeStrict' line)
let readH :: [Either String Task] -> IO [Either String Task]
readH theRest = do
isDone <- condition
if isDone
then return theRest
else do
thisStep <- takeOneStep
readH (thisStep : theRest)
out <- readH []
Re-read the body of readH at this point. Notice that none of it is specific to this particular task anymore. It now describes a general sort of looping over takeOneStep until condition holds. In fact, it had that generic structure the whole time! It's just that the generic structure can be seen now that we've renamed the task-specific bits. By making takeOneStep and condition arguments of the function, we arrive at the desired combinator.
untilIO :: IO Bool -> IO (Either String Task) -> [Either String Task] -> IO [Either String Task]
untilIO condition takeOneStep theRest = do
isDone <- condition
if isDone
then return theRest
else do
thisStep <- takeOneStep
untilIO (thisStep : theRest)
Notice that this combinator, as implemented, doesn't have to be constrained to Either String Task; it can work for any type a instead of Either String Task.
untilIO :: IO Bool -> IO a -> [a] -> IO [a]
Notice that this combinator, as implemented, doesn't have to even be constrained to IO. It can work for any Monad m instead of IO.
untilM :: Monad m => m Bool -> m a -> [a] -> m [a]
The moral of the story is this: by figuring how to write "looping over a monadic predicate" via explicit recursion for your particular use case, you have already written the general combinator! It's right there in the structure of your code, waiting to be discovered.
There are a couple ways this could be cleaned up further, such as removing the [] argument and building up the list in order (currently the list comes out reversed, you'll notice), but those are beyond the point I'm trying to make right now, and so are left as exercises to the reader. Assuming you've done both of those things, you end up with
untilM :: m Bool -> m a -> m [a]
Which I would use in your example like so:
(_, (Just stdout), _, _) <- createProcess (proc "task" (args fl)){ std_out = CreatePipe }
out <- untilM (hIsEof stdout) $ do
line <- hGetLine stdout
return (eitherDecodeStrict' line)
Looks a lot like an imperative-style "until" loop!
If you swap the argument order, then you end up with something nearly equivalent to Control.Monad.Loops.untilM. Note that unlike our solution here, Control.Monad.Loops.untilM (annoyingly!) always performs the action before checking the condition, so it's not quite safe for use in this case if you might be dealing with empty files. They apparently expect you to use untilM infix, which makes it look like a do-while, hence the flipped arguments and "body then condition" nonsense.
(do ...
...
) `untilM` someCondition

How to use maybe monad inside another monad?

I have this code (inside happstack, but could be just the IO monad):
accountHandler conn = do
sessionId <- optional $ readCookieValue "sessionId"
case sessionId of
Nothing -> seeOther ("/" :: String) $ toResponse ()
Just s -> do
result <- loggedInUserId conn s
case result of
Just userId -> seeOther ("/account/" ++ unUserId userId) $ toResponse ()
Nothing -> seeOther ("/" :: String) $ toResponse ()
I want to remove the nested case statements and write something like:
accountHandler conn = do
let action = do
sessionId <- optional $ readCookieValue "sessionId"
userId <- loggedInUserId conn sessionId
return $ seeOther ("/account/" ++ userId)
maybe (seeOther ("/" :: String)) id action $ toResponse ()
... but userId ends up as a type of Maybe String rather than just String. How can I evaluate the nested do block using the maybe monad? (I would also accept a different refactoring that removes the nested cases.)
UPDATE: Below is a generic, though contrived, version of the same problem:
module Main where
getAnswer expected = do
l <- getLine
if l == expected
then return $ Just l
else return $ Nothing
main = do
a <- getAnswer "a"
case a of
Nothing -> putStrLn "nope"
Just x -> do
b <- getAnswer x
case b of
Nothing -> putStrLn "nope"
Just _ -> putStrLn "correct!"
Ok, with your generic example I could do something with Control¸Monad.Transformers. This allows you to create a stack of monads. You can check it out here: http://hackage.haskell.org/package/transformers-0.3.0.0/docs/Control-Monad-Trans-Maybe.html
You can apply MaybeT to everything of type IO (Maybe a) and then do all the computations in the inner do block and then check for Nothing at the end.
module Main where
import Control.Monad.Trans.Maybe
getAnswer expected = MaybeT $ do
l <- getLine
if l == expected
then return $ Just l
else return $ Nothing
main = do
y <- runMaybeT $ do a <- getAnswer "a"
b <- getAnswer a
return b
case y of Nothing -> putStrLn "failure"
(Just _) -> putStrLn "correct"
Another version using liftIO and the Alternative type class:
module Main where
import Control.Monad.Trans.Maybe
import Control.Monad.IO.Class
import Control.Applicative
getAnswer expected = MaybeT $ do
l <- getLine
if l == expected
then return $ Just l
else return $ Nothing
main = do
_ <- runMaybeT $ do a <- getAnswer "a"
b <- getAnswer a
liftIO $ putStrLn "correct"
<|> do liftIO $ putStrLn "failure"
return ()
But using many lift operations is not very elegant.
I'd like to add to MoFu's answer that once you have MaybeT IO, you can use the full power of its MonadPlus instance. For example, if you need to check that some condition holds, use guard or mfilter. So you can write:
import Control.Monad
import Control.Monad.IO.Class
import Control.Monad.Trans
import Control.Monad.Trans.Maybe
getAnswer :: (MonadPlus m, MonadIO m) => String -> m String
getAnswer expected = mfilter (== expected) $ liftIO getLine
It's type is very generic, it works for any monad that is MonadPlus and MonadIO. This is handy if you decide to modify your monad stack later. But we could also use more specific type (MonadIO m) => String -> MaybeT m String.
For extracting a MaybeT IO value from your inner computation I'd suggest to write a variant of fromMaybe for MaybeT:
fromMaybeT :: (Monad m) => m a -> MaybeT m a -> m a
fromMaybeT onFail = maybe onFail return <=< runMaybeT
It extracts the result with runMaybeT. If it's Just, just return it, otherwise run onFail action.
Combined together, we get:
main = fromMaybeT (putStrLn "nope") $ do
a <- getAnswer "a"
b <- getAnswer a
liftIO $ putStrLn "correct!"

Resources