while :: Int -> Bool -> (Int,Int) -> (Int,Int) ->[Int] -> String
while arguments validity premRange atomRange operators =
return(if validity then "Hello" else "NO")
main :: IO()
main =
do
putStrLn "Welcome to Random Argument Generator"
arguments <- getArguments
validity <- getValidity
putStrLn "Enter the range of the number of premises to each argument"
premRange <- getRange
putStrLn "Enter the range of the number of atomic statments per premises"
atomRange <- getRange
operators <- getOperators
putStrLn "Thank You!\nExecuting..."
test <- while arguments validity premRange atomRange operators
putStrLn "Good Bye"
Its complaining about my return in while and my call to it. i made this function as a test and im really confused as to what its complaining about exactly.
In Haskell an expression such as an if expression is a perfectly fine definition for a function. You can just remove the word return.
After that, you're going to have a problem in main where one line doesn't do I/O, so its type isn't compatible with the surrounding do (I think):
test <- while arguments validity premRange atomRange operators
But, aha, you can change it to:
let test = while arguments validity premRange atomRange operators
Related
I am using the Idone.com site and wanted to run this code but do not know the syntax putStrLn to compile from stdin Use this code but strip error.
main = putStrLn (show (sumaCifras x))
sumaCifras:: Int -> Int
sumaCifras x = div x 1000 + mod (div x 100) 10 + mod (div x 10) 10 + mod x 10
Compiler is having a problem, because you use x in main function, which isn't bound in this scope. At first you must read a value from input and then pass it to your function. You can do it in 2 ways.
More natural for people used to imperative languages is "do" syntax, in which it will look like that:
main = do
x <- getLine
putStrLn (show (sumaCifras (read x :: Int)))
When you want to use x as Int, you must use "read" function with type signature, so compiler will know what to expect.
To write it in more functional way, you may use monad transformations, to pass it like that
main = getLine >>= (\x -> putStrLn(show (sumaCifras (read x :: Int)))
The ">>=" operator will get result value from first monadic action (in here it is IO action of getting input) and apply it to function on the right (in here it is lambda function that reads input as Integer, applies your function and returns it to putStrLn, which prints it on the screen). "do" syntax is essentially just a syntactic sugar for this monadic operations, so it will not affect the execution or performance of program.
You can go one step further in writing it functionally by writing it totally point-free
main = getLine >>= (putStrLn . show . sumaCifras . (read :: String -> Int))
Note that here you have type signature for read function, not for application of this function to argument, hence the String -> Int. In here first executed is the getLine function. Input obtained from it is then passed to the read, where it is casted to Int, next is sumaCifras, which then is casted to String by show and printed with putStrLn.
///Edit
I have a problem with haskell. If someone can help me, that would be great.
I'm inserting records into a file using the following code:
check :: Int -> Int
check a
|a > 0 && a<=10 = a
|otherwise = error "oh. hmm.. enter a number from the given interval"
ame :: IO ()
ame = do
putStr "Enter the file name: "
name <- getLine
putStrLn "Do you want to add new records? "
question <- getLine
if question == "yes" then do
putStrLn "Enter your records:"
newRec <- getLine
appendFile name ('\n':newRec)
--new lines--
putStrLn "enter a number between 0 and 10: "
something <- getLine
return (read something:: Int)
let response = check something
putStrLn response
appendFile name ('\n':something)
putStrLn "enter something new again: "
something2 <- getLine
appendFile name ('\n':something2)
putStrLn "a"
else
putStr "b"
Now I want to extract some records from this file, using a specific criteria. For example, i want to extract and display records from even(or odd or any other criteria) rows. can I do that? if yes, how?
Also...
I want to check the user input. Let's say that I don't want him/her to enter a string instead of an integer. can I also check his/her input? do I need to create another function and call that function inside the code from above?
///Edit
thank you for answering. but how can i embed it into my previous code?
I've tried now to create a function(you can see the above code) and then call that function in my IO. but it doesn't work..
Yes, it is certainly possible to display only certain rows. If you want to base it off of the row number, the easiest way is to use zip and filter
type Record = String
onlyEven :: [Record] -> [Record]
onlyEven records =
map snd $ -- Drop the numbers and return the remaining records
filter (even . fst) $ -- Filter by where the number is even
zip [1..] -- All numbers
records -- Your records
This technique can be used in a lot of circumstances, you could even abstract it a bit to
filterByIdx :: Integral i => (i -> Bool) -> [a] -> [a]
filterByIdx condition xs = map snd $ filter (condition . fst) $ zip [1..] xs
-- Could also use 0-based of `zip [0..] xs`, up to you
onlyEven :: [a] -> [a]
onlyEven = filterByIdx even
If you want to check if an input is an Int, the easiest way is to use the Text.Read.readMaybe function:
import Text.Read (readMaybe)
promptUntilInt :: IO Int
promptUntilInt = do
putStr "Enter an integer: "
response <- getLine
case readMaybe response of
Just x -> return x
Nothing -> do
putStrLn "That wasn't an integer!"
promptUntilInt
This should give you an idea of how to use the function. Note that in some cases you'll have to specify the type signature manually as case (readMaybe response :: Maybe Int) of ..., but here it'll work fine because it can deduce the Int from promptUntilInt's type signature. If you get an error about how it couldn't figure out which instance for Read a to use, you need to manually specify the type.
You have
something <- getLine
return (read something:: Int)
let response = check something
putStrLn response
To step through what you're trying to do with these lines:
something <- getLine
getLine has the type IO String, meaning it performs an IO action and returns a String. You can extract that value in do notation as
something <- getLine
Just as you have above. Now something is a String that has whatever value was entered on that line. Next,
return (read something :: Int)
converts something to an Int, and then passes it to the function return. Remember, return is not special in Haskell, it's just a function that wraps a pure value in a monad. return 1 :: Maybe Int === Just 1, for example, or return 1 :: [Int] === [1]. It has contextual meaning, but it is no different from the function putStrLn. So that line just converts something to an Int, wraps it in the IO monad, then continues on to the next line without doing anything else:
let response = check something
This won't compile because check has the type Int -> Int, not String -> String. It doesn't make any sense to say "hello, world" > 0 && "hello, world" <= 10, how do you compare a String and an Int? Instead, you want to do
let response = check (read something)
But again, this is unsafe. Throwing an error on an invalid read or when read something is greater than 10 will crash your program completely, Haskell does errors differently than most languages. It's better to do something like
check :: Int -> Bool
check a = a > 0 && a <= 10
...
something <- getLine
case readMaybe something of
Nothing -> putStrLn "You didn't enter a number!"
Just a -> do
if check a
then putStrLn "You entered a valid number!"
else putStrLn "You didn't enter a valid number!"
putStrLn "This line executes next"
While this code is a bit more complex, it's also safe, it won't ever crash and it handles each case explicitly and appropriately. By the way, the use of error is usually considered bad, there are limited capabilities for Haskell to catch errors thrown by this function, but errors can be represented by data structures like Maybe and Either, which give us pure alternatives to unsafe and unpredictable exceptions.
Finally,
putStrLn response
If it was able to compile, then response would have the type Int, since that's what check returns. Then this line would have a type error because putStrLn, as the name might suggest, puts a string with a new line, it does not print Int values. For that, you can use print, which is defined as print x = putStrLn $ show x
Since this is somewhat more complex, I would make a smaller function to handle it and looping until a valid value is given, something like
prompt :: Read a => String -> String -> IO a
prompt msg failMsg = do
putStr msg
input <- getLine
case readMaybe input of
Nothing -> do
putStrLn failMsg
prompt
Just val -> return val
Then you can use it as
main = do
-- other stuff here
-- ...
-- ...
(anInt :: Int) <- prompt "Enter an integer: " "That wasn't an integer!"
-- use `anInt` now
if check anInt
then putStrLn $ "Your number multiplied by 10 is " ++ show (anInt * 10)
else putStrLn "The number must be between 1 and 10 inclusive"
You don't have to make it so generic, though. You could easily just hard code the messages and the return type like I did before with promptUntilInt.
How can I print the result of sum of two numbers?
main:: IO()
main = do putStrLn "Insert the first value: "
one <- getLine
putStrLn "Insert the second value: "
two <- getLine
putStrLn "The result is:"
print (one+two)
This gives me an error:
ERROR file:.\IO.hs:3 - Type error in application
*** Expression : putStrLn "The result is:" print (one + two)
*** Term : putStrLn
*** Type : String -> IO ()
*** Does not match : a -> b -> c -> d
Try to use readLn instead of getLine.
getLine returns a String in the IO monad and Strings cannot be added.
readLn has polymorphic return type, and the compiler infers that the return type is Integer (in the IO monad) so you can add them.
I'm going to take a guess that your error is related to not using parens.
Also, since getLine produces a string, you'll need to convert it to the correct type. We can use read to get a number from it, although it's possible it will cause an error if the string cannot be parsed, so you might want to check it only contains numbers before reading.
print (read one + read two)
Depending on precedence, the variables may be parsed to belong as parameters for print instead of to +. By using parens, we ensure the variables are associated with + and only the result of that is for print.
Lastly, make sure the indentation is correct. The way you've pasted it here is not correct with the do-expression. The first putStrLn should be on the same indentation level as the rest - at least ghc complains about it.
You can modify your code this way using the read :: Read a => String -> a
main:: IO()
main = do putStrLn "Insert the first value: "
one <- getLine
putStrLn "Insert the second value: "
two <- getLine
putStrLn "The result is:"
print ((read one) + (read two))
I am lost in this concept. This is my code and what it does is just asking what is your name.
askName = do
name <- getLine
return ()
main :: IO ()
main = do
putStrLn "Greetings once again. What is your name?"
askName
However, How can I access in my main the variable name taken in askName?
This is my second attempt:
askUserName = do
putStrLn "Hello, what's your name?"
name <- getLine
return name
sayHelloUser name = do
putStrLn ("Hey " ++ name ++ ", you rock!")
main = do
askUserName >>= sayHelloUser
I can now re-use the name in a callback way, however if in main I want to call name again, how can I do that? (avoiding to put name <- getLine in the main, obviously)
We can imagine that you ask the name in order to print it, then let's rewrite it.
In pseudo code, we have
main =
print "what is your name"
bind varname with userReponse
print varname
Your question then concern the second instruction.
Take a look about the semantic of this one.
userReponse is a function which return the user input (getLine)
varname is a var
bind var with fun : is a function which associate a var(varname) to the output of a function(getLine)
Or as you know in haskell everything is a function then our semantic is not well suited.
We need to revisit it in order to respect this idiom. According to the later reflexion the semantic of our bind function become bind fun with fun
As we cannot have variable, to pass argument to a function, we need, at a first glance, to call another function, in order to produce them. Thus we need a way to chain two functions, and it's exactly what's bind is supposed to do. Furthermore, as our example suggest, an evaluation order should be respected and this lead us to the following rewriting with fun bind fun
That's suggest that bind is more that a function it's an operator.
Then for all function f and g we have with f bind g.
In haskell we note this as follow
f >>= g
Furthermore, as we know that a function take 0, 1 or more argument and return 0, 1 or more argument.
We could refine our definition of our bind operator.
In fact when f doesn't return any result we note >>= as >>
Applying, theses reflexions to our pseudo code lead us to
main = print "what's your name" >> getLine >>= print
Wait a minute, How the bind operator differ from the dot operator use for the composition of two function ?
It's differ a lot, because we have omit an important information, bind doesn't chain two function but it's chain two computations unit. And that's the whole point to understand why we have define this operator.
Let's write down a global computation as a sequence of computation unit.
f0 >>= f1 >> f2 >> f3 ... >>= fn
As this stage a global computation could be define as a set of computation unit with two operator >>=, >>.
How do we represent set in computer science ?
Usually as container.
Then a global computation is a container which contain some computation unit. On this container we could define some operator allowing us to move from a computation unit to the next one, taking into account or not the result of the later, this is ours >>= and >> operator.
As it's a container we need a way to inject value into it, this is done by the return function. Which take an object and inject it into a computation, you could check it through is signature.
return :: a -> m a -- m symbolize the container, then the global computation
As it's a computation we need a way to manage a failure, this done by the fail function.
In fact the interface of a computation is define by a class
class Computation
return -- inject an objet into a computation
>>= -- chain two computation
>> -- chain two computation, omitting the result of the first one
fail -- manage a computation failure
Now we can refine our code as follow
main :: IO ()
main = return "What's your name" >>= print >> getLine >>= print
Here I have intentionally include the signature of the main function, to express the fact that we are in the global IO computation and the resulting output with be () (as an exercise enter $ :t print in ghci).
If we take more focus on the definition for >>=, we can emerge the following syntax
f >>= g <=> f >>= (\x -> g) and f >> g <=> f >>= (\_ -> g)
And then write
main :: IO ()
main =
return "what's your name" >>= \x ->
print x >>= \_ ->
getLine >>= \x ->
print x
As you should suspect, we certainly have a special syntax to deal with bind operator in computational environment. You're right this is the purpose of do syntax
Then our previous code become, with do syntax
main :: IO ()
main = do
x <- return "what's your name"
_ <- print x
x <- getLine
print x
If you want to know more take a look on monad
As mentioned by leftaroundabout, my initial conclusion was a bit too enthusiastic
You should be shocked, because we have break referential transparency law (x take two different value inside our sequence of instruction), but it doesn't matter anymore,because we are into a computation, and a computation as defined later is a container from which we can derive an interface and this interface is designed to manage, as explain, the impure world which correspond to the real world.
Return the name from askname. In Haskell its not idiomatic to access "global" variables:
askName :: IO String
askName = do
name <- getLine
return name
main :: IO ()
main = do
putStrLn "Greetings once again. What is your name?"
name <- askName
putStrLn name
Now the only problem is tht the askName function is kind of pointless, since its now just an alias to getLine. We could "fix" that by putting the question inside askName:
askName :: IO String
askName = do
putStrLn "Greetings once again. What is your name?"
name <- getLine
return name
main :: IO ()
main = do
name <- askName
putStrLn name
Finally, just two little points: its usually a good idea to put type declarations when you are learning, to make things explicit and help compiler error messages. Another thing is to remember that the "return" function is only used for monadic code (it is not analogous to a traditional return statement!) and sometimes we could have ommited some intermediary variables:
askName :: IO String
askName = do
putStrLn "Greetings once again. What is your name?"
getLine
I know that the following "do" notation's "bind" function is equivalent to getLine >>= \line -> putStrLn
do line <- getLine
putStrLn line
But how is the following notation equivalent to bind function?
do line1 <- getLine
putStrLn "enter second line"
line2 <- getLine
return (line1,line2)
I take it you are trying to see how to bind the result of "putStrLn". The answer is in the type of putStrLn:
putStrLn :: String -> IO ()
Remember that "()" is the unit type, which has a single value (also written "()"). So you can bind this in exactly the same way. But since you don't use it you bind it to a "don't care" value:
getLine >>= \line1 ->
putStrLn "enter second line" >>= \_ ->
getline >>= \line2 ->
return (line1, line2)
As it happens, there is an operator already defined for ignoring the return value, ">>". So you could just rewrite this as
getLine >>= \line1 ->
putStrLn "enter second line" >>
getline >>= \line2 ->
return (line1, line2)
I'm not sure if you are also trying to understand how bind operators are daisy-chained. To see this, let me put the implicit brackets and extra indentation in the example above:
getLine >>= (\line1 ->
putStrLn "enter second line" >> (
getline >>= (\line2 ->
return (line1, line2))))
Each bind operator links the value to the left with a function to the right. That function consists of all the rest of the lines in the "do" clause. So the variable being bound through the lambda ("line1" in the first line) is in scope for the whole of the rest of the clause.
For this specific example you can actually avoid both do and >>= by using combinators from Control.Applicative:
module Main where
import Control.Applicative ((<$>), (<*>), (<*))
getInput :: IO (String, String)
getInput = (,) <$> getLine <* putStrLn "enter second line" <*> getLine
main = print =<< getInput
Which works as expected:
travis#sidmouth% ./Main
hello
enter second line
world
("hello","world")
It looks a little weird at first, but in my opinion the applicative style feels very natural once you're used to it.
I would strongly suggest you to read the chapter Desugaring of Do-blocks in the book Real-World haskell. It tells you, that you all are wrong. For a programmer, it's the natural way to use a lambda, but the do-block is implemented using functions which - if a pattern maching failuire occurs - will call the fail implementation of the according monad.
For instance, your case is like:
let f x =
putStrLn "enter second line" >>
let g y = return (x,y)
g _ = fail "Pattern mismatched"
in getLine >>= g
f _ = fail "Pattern mismatched"
in getLine >>= f
In a case like this, this may be completely irrelevant. But consider some expression that involves pattern-matching. Also, you can use this effect for some special stuff, eg, you can do something like this:
oddFunction :: Integral a => [a] -> [a]
oddFunctiond list = do
(True,y) <- zip (map odd list) list
return y
What will this function do? You can read this statement as a rule for working with the elements of the list. The first statement binds an element of the list to the var y, but only if y is odd. If y is even, a pattern matching failure occurs and fail will be called. In the monad instance for Lists, fail is simply []. Thus, the function strips all even elements from the list.
(I know, oddFunction = filter odd would do this better, but this is just an example)
getLine >>= \line1 ->
putStrLn "enter second line" >>
getLine >>= \line2 ->
return (line1, line2)
Generally foo <- bar becomes bar >>= \foo -> and baz becomes baz >> (unless it's the last line of the do-block, in which case it just stays baz).