I understand how to use recursive data structures to manage a list of thingies:
data Thingy a = NoThingy | Thingy a a (Thingy a) deriving (Show, Read)
firstThingsFirst :: a -> a -> (Thingy a)
firstThingsFirst a b = Thingy a b NoThingy
andAnotherThing :: a -> a -> Thingy a -> Thingy a
andAnotherThing a b NoThingy = Thingy a b NoThingy
andAnotherThing a b things = Thingy a b things
And in ghci I can do something like:
let x=andAnotherThing "thing1" "thing2" NoThingy
let y=andAnotherThing "thing3" "thing4" x
However, I don't know how to make this work for a compiled program which takes user input. In other words, I want to let a user fill up the structure. Something like:
import System.IO
allThings=NoThingy
main = do
putStrLn "First Thing"
first<-getLine
putStrLn "Second Thing"
second<-getLine
let allThings=Thingy first second allThings
print allThings
main
Values in Haskell are immutable, so if you "add an item to a list", you get a new list. So in your code above, the
let allThings = Thingy first second allThings
doesn't do what you expect. The top-level allThings has the value NoThingy and that cannot change. The name allThings in the let-binding doesn't refer to the top-level entity, it introduces a new binding shadowing the top-level name, and that new name is also referenced on the right hand side of the binding.
So that line and the following are equivalent to
let theThings = Thingy first second theThings
print theThings
The let-binding creates a cyclic structure, referring to itself as one of its components. That means of course that printing it will never finish.
What you (probably) want to do requires passing the structure you want to update as a parameter
loop things = do
putStrLn "First Thing"
...
let newThings = Thingy first second things
print newThings
loop newThings
And of course, like Nicolas said, you probably want to convert the input strings to values of appropriate type.
What you create is an infinitely self-referential "allThings" that gets printed.
You are binding to the name allThings twice. The first time before main and the second time before print.
The second binding refers to allThings at then end of the right hand side. This reference is NOT to the first binding. This reference is to the second binding itself.
If you change the name of the second binding and of the print:
main = do
putStrLn "First Thing"
first <- getLine
putStrLn "Second Thing"
second <- getLine
let allThings2 = Thingy (read first) (read second) allThings
print allThings2
main
then you will get a single Thingy printed on each loop of main. Since you want to accumulate the answers you can define a tail-recursive "query" like this:
query old = do
putStrLn "First Thing"
first<-getLine
putStrLn "Second Thing"
second<-getLine
let new=Thingy first second old
print new
query new
main = query NoThingy
The above may do what you are looking for.
It sounds like you're asking for a way to convert from user input of type String to a value of type Thingy. Since your Thingy type already has an instance for Read, you can use the read function:
read :: Read a => String -> a
This makes your main function more like:
main = do
putStrLn "First Thing"
first <- getLine
putStrLn "Second Thing"
second <- getLine
let allThings = Thingy (read first) (read second) allThings
print allThings
main
Of course, if you enter a string that doesn't correspond to a Thingy, then you'll get an error, so you might want to use readMay from the safe package instead:
readMay :: Read a => String -> Maybe a
Another problem is that the type inference can't guess which type a is intended, so you'll also have to give it a hint, by maybe having something like:
let allThings = Thingy (read first :: Int) (read second :: String) allThings
It's probably worth noting that in this definition, allThings is an infinite structure, and will take forever to print: the last call to main will never be reached.
The problem is that you are trying to use a variable to hold mutable state (like one would do in an imperative language) but you can't do so in Haskell. All state must be explicitly passed as arguments to your functions. As pointed in the other answers, the allThings inside main is actually a separate variable from the allThings in the global scope (it just shadows the same name)
The following example shows how to build a program that loops forever while building up a list of numbers. I think this is kind of what you want to do and it shouldn't be hard to adapt it to "Thingies"
In our case the state we have to keep for our loop is the index of the next number to be entered (1st, 2nd, etc) and the list of numbers that we have already been read. Our loop function will thus receive this state as an argument and return an IO action.
module Main where
-- Explicit signature so readLn and show don't complain...
loop_step :: (Int, [Int]) -> IO ()
loop_step (i,xs) = do
putStrLn ("Enter the " ++ show i ++ "th number:")
n <- readLn
let newList = n : xs
print newList
loop_step (i+1, newList)
main :: IO ()
main = do
loop_step (1, [])
Related
If Haskell is lazy, why does getLine is evaluated in both of the following cases? Being lazy I would expect that in the case of fa the getLine would not be evaluated because its result is not being used subsequently:
let fa = do {
x <- getLine;
return "hello"
}
let fb = do {
x <- getLine;
return $ x
}
(I tested both cases in GHCi)
Thanks
Its result is being used, just not in the way you necessarily expect. This de-sugars to
fa = getLine >>= (\x -> return "hello")
So the result of getLine is still passed to the function \x -> return "hello". Monads are inherently about sequencing actions together (among other things); that sequencing still occurs even if results are later not used. If that weren't the case, then
main = do
print "Hello"
print "World"
wouldn't do anything as a program, since the results of both calls to print aren't being used.
Congratulations, you've just discovered why Haskell is a pure functional language!
The result† of getLine is not a string. It's an IO action which happens to “produce” a string. That string is indeed not evaluated, but the action itself is (since it turns up in a do block bound to main), and this is all that matters as far as side-effects are concerned.
†Really just the value of getLine. This is not a function, so it doesn't actually have a result.
Be careful now... ;-)
The result of getLine isn't a string, it's an "I/O command object", if you will. The code actually desugars to
getLine >>= (\ x -> return "hello")
The >>= operator constructs a new I/O command object out of an existing one and a function... OK, that's a bit much to wrap your mind around. The important thing is, the I/O action gets executed (because of the implementation of >>= for IO), but its result doesn't necessarily get evaluated (because of laziness).
So let's look at the implementation of the IO monad... erm, actually you know what? Let's not. (It's deep magic, hard-wired into the compiler, and as such it's implementation-specific.) But this phenomenon isn't unique to IO by any means. Let's look at the Maybe monad:
instance Monad Maybe where
mx >>= f =
case mx of
Nothing -> Nothing
Just x -> f x
return x = Just x
So if I do something like
do
x <- foobar
return "hello"
Will x get evaluated? Let's look. It desugars to:
foobar >>= (\ x -> return "hello")
then this becomes
case foobar of
Nothing -> Nothing
Just x -> Just "hello"
As you can see, foobar is clearly going to be evaluated, because we need to know whether the result is Nothing or Just. But the actual x won't be evaluated, because nothing looks at it.
It's kind of the same way that length evaluates the list nodes, but not the list elements they point to.
I would like to allow a user to build a list from a series of inputs in Haskell.
The getLine function would be called recursively until the stopping case ("Y") is input, at which point the list is returned.
I know the function needs to be in a similar format to below. I am having trouble assigning the correct type signatures - I think I need to include the IO type somewhere.
getList :: [String] -> [String]
getList list = do line <- getLine
if line == "Y"
then return list
else getList (line : list)
So there's a bunch of things that you need to understand. One of them is the IO x type. A value of this type is a computer program that, when later run, will do something and produce a value of type x. So getLine doesn't do anything by itself; it just is a certain sort of program. Same with let p = putStrLn "hello!". I can sequence p into my program multiple times and it will print hello! multiple times, because the IO () is a program, as a value which Haskell happens to be able to talk about and manipulate. If this were TypeScript I would say type IO<x> = { run: () => Promise<x> } and emphatically that type says that the side-effecting action has not been run yet.
So how do we manipulate these values when the value is a program, for example one that fetches the current system time?
The most fundamental way to chain such programs together is to take a program that produces an x (an IO x) and then a Haskell function which takes an x and constructs a program which produces a y (an x -> IO y and combines them together into a resulting program producing a y (an IO y.) This function is called >>= and pronounced "bind". In fact this way is universal, if we add a program which takes any Haskell value of type x and produces a program which does nothing and produces that value (return :: x -> IO x). This allows you to use, for example, the Prelude function fmap f = (>>= return . f) which takes an a -> b and applies it to an IO a to produce an IO b.
So It is so common to say things like getLine >>= \line -> putStrLn (upcase line ++ "!") that we invented do-notation, writing this as
do
line <- getLine
putStrLn (upcase line ++ "!")
Notice that it's the same basic deal; the last line needs to be an IO y for some y.
The last thing you need to know in Haskell is the convention which actually gets these things run. That is that, in your Haskell source code, you are supposed to create an IO () (a program whose value doesn't matter) called Main.main, and the Haskell compiler is supposed to take this program which you described, and give it to you as an executable which you can run whenever you want. As a very special case, the GHCi interpreter will notice if you produce an IO x expression at the top level and will immediately run it for you, but that is very different from how the rest of the language works. For the most part, Haskell says, describe the program and I will give it to you.
Now that you know that Haskell has no magic and the Haskell IO x type just is a static representation of a computer program as a value, rather than something which does side-effecting stuff when you "reduce" it (like it is in other languages), we can turn to your getList. Clearly getList :: IO [String] makes the most sense based on what you said: a program which allows a user to build a list from a series of inputs.
Now to build the internals, you've got the right guess: we've got to start with a getLine and either finish off the list or continue accepting inputs, prepending the line to the list:
getList = do
line <- getLine
if line == 'exit' then return []
else fmap (line:) getList
You've also identified another way to do it, which depends on taking a list of strings and producing a new list:
getList :: IO [String]
getList = fmap reverse (go []) where
go xs = do
x <- getLine
if x == "exit" then return xs
else go (x : xs)
There are probably several other ways to do it.
I am a beginner to functional programming and Haskell as a programming language. After given an input of numbers from the command line I want to put those numbers into a list, then pass that list as a parameter to calculate its sum. Here's what I am working on:
import Data.List
iotxt :: IO ()
main :: IO ()
l1 = []
iotxt = do a <- getLine
-- read in numbers that are not equal to -1
insert (read a) l1
if (not ((read a) == -1.0))
then iotxt
else do return ()
main = do
putStrLn("Enter a number [-1 to quit]")
iotxt
-- size of the list
print(length [l1])
-- sum
But when I attempt to place the values inside the list I get this error:
Couldn't match expected type `IO a0' with actual type `[a1]'
In the return type of a call of `insert'
In a stmt of a 'do' block: insert (read a) l1
In the expression:
do { a <- getLine;
insert (read a) l1;
if (not ((read a) == - 1.0)) then iotxt else do { return () } }
There are multiple things wrong with you're code.
Starting from the bottom up, first, length [l1] doesn't make sense. Any [ ] with only one item in between is just that: a list with a single item, so the length will always be 1. You certainly mean length l1 here, i.e. length of the list l1, not length of the list ᴄᴏɴᴛᴀɪɴɪɴɢ only l1.
Next, you have this iotxt and try to make it modify the "global variable" l1. You can't do that, Haskell does not have any such thing as mutable global variables – for good reasons; global mutable state is considered evil even in imperative languages. Haskell kind of has local variables, through IORefs, but using those without good reason is frowned upon. You don't really need them for something like this here.
The correct thing to do is to scrap this global l1 binding, forget about mutating variables. Which brings us to the question of how to pass on the information acquired in iotxt. Well, the obvious functional thing to do is, returning it. We need to make that explicit in the type (which is again a good thing, so we actually know how to use the function):
ioTxt :: IO [Int]
Such a function can then nicely be used in main:
main :: IO ()
main = do
putStrLn "Enter a number [-1 to quit]"
l1 <- ioTxt
print $ length l1
You see: almost the same as your approach, but with proper explicit introduction of l1 where you need it, rather than somewhere completely different.
What's left to do is implementing ioTxt. This now also needs a local l1 variable since we have scrapped the global one. And when you implement a loop as such a recursive call, you need to pass an updated version of it to each instantiation. The recursion itself should be done on a locally-defined function.
ioTxt :: IO [Int]
ioTxT = go [] -- Start with empty list. `go` is a widespread name for such simple "loop functions".
where go l1 = do
a <- getLine
let x = read a :: Int
case x of
(-1) -> return l1
_ -> go (insert x l1)
In the last line, note that insert does not modify the list l1, it rather creates a new one that equals the old one except for having the new element in it. And then passes that to the next loop-call, so effectively you get an updated list for each recursive call.
Also note that you probably shouldn't use insert here: that's specifically for placing the new element at the right position in an ordered list. If you just want to accumulate the values in some way, you can simply use
_ -> go $ x : l1
In haskell, there are no variables, everything is immutable. So you shouldn't define l1 and change its value later, which doesn't work.
Instead you should think how to write iotxt properly and let it collect elements and pass the input list back to your main.
In your iotxt, you can think about these two situations:
if the input is -1, then we can just pass an empty list [] back, wrap it inside the IO by return []
if the input is not -1, we can first store this value somewhere, say result. After that, we should call iotxt recursively and let this inner iotxt handle the rest of the inputs. Finally, we will get return value rest, then we just simply put result and rest together.
Moreover, you can think of IO a like some program (which might have side effects like reading from input or writing to output) that returns a value of type a. According to the definition of your iotxt, which is a program that reads input until meeting a -1 and gives you the list in return, the type signature for iotxt should be IO [Float].
There's a length [l1] in your code, which constructs a list with only one element(i.e. l1) and thus length [l1] will always return 1. Instead of doing this, you can say length l1, which calculates the length of l1.
Finally, you don't need to group function arguments by parenthese, just simply say f x if you want to call f with x.
I've modified your code a little bit, hope it can give you some help.
import Data.List
-- iotxt reads from stdin, yields [Float]
-- stop reading when "-1" is read
iotxt :: IO [Float]
main :: IO ()
iotxt = do
a <- getLine
-- read in numbers that are not equal to -1
let result = (read a) :: Float
if (not (result == -1.0))
then do
-- read rest of the list from stdin
rest <- iotxt
-- put head & tail together
return $ result:rest
else do return []
main = do
putStrLn("Enter a number [-1 to quit]")
l1 <- iotxt
-- size of the list
print $ length l1
-- sum
print $ sum l1
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 wonder can a IO() function return tuple because i would like to get these out of this function as input for another function.
investinput :: IO()->([Char], Int)
investinput = do
putStrLn "Enter Username : "
username <- getLine
putStrLn "Enter Invest Amount : "
tempamount <- getLine
let amount = show tempamount
return (username, amount)
Please help.
Thanks.
IO in Haskell doesn't work like IO in the languages you're used to. All functions in Haskell must be pure: that is, if a function f is called with the argument x, there must be no difference between calling it once, twice, or a hundred times. Consider what this means for IO, though. Naïvely, getLine should have the type getLine :: String, or perhaps getLine :: () -> String. (() is the unit type, whose only value is (); it's sort of like a void type in a C-like language, but there is a single value of it.) But this would mean that every time you wrote getLine, it would have to return the same string, which is not what you want. This is the purpose of the IO type: to encapsulate actions. These actions are distinct from functions; they represent impure computation (though they themselves are pure). A value of type IO a represents an action which, when executed, returns a value of type a. Thus, getLine has type getLine :: IO String: every time the action is evaluated, a String is produced (by reading from the user). Similarly, putStr has type putStr :: String -> IO (); it is a function which takes a string and returns an action which, when run, returns no useful information… but, as a side effect, prints something to the screen.
You are attempting to write a function of type IO () -> ([Char], Int). This would be a function which took as input an action and returned a tuple, which is not what you want. You want an IO (String, Int)—an action which, when run, produces a tuple consisting of a string (which is a synonym for [Char]) and an integer. You're almost there with your current code, too! This is what you'll need instead:
investinput :: IO (String, Int)
investinput = do
putStrLn "Enter Username : "
username <- getLine
putStrLn "Enter Invest Amount : "
tempamount <- getLine
let amount = read tempamount
return (username, amount)
Notice that I've only made two changes (and removed a blank line). First, I've changed the type of the function, like I said above. Second, I changed show into read. The show function has the type Show a => a -> String: it is a function which takes anything which can be shown and produces a string representing it. You wanted read, which has the type Read a => String -> a: given a string, it parses it and returns some readable value.
The other thing you asked about is returning a tuple (String, Int) instead of an action IO (String, Int). There is no pure way to do this; in other words, there is no pure function IO a -> a. Why is this? Because IO a represents an impure action which depends on the real world. If we had such a function impossibleRunIO :: IO a -> a, then we would want it to be the case that impossibleRunIO getLine == impossibleRunIO getLine, since the function must be pure. But this is useless, as we would want impossibleRunIO to be able to actually interact with the real world! Thus, this pure function is impossible. Everything that enters IO can never leave. This is what return does: it is a function with, in this case1, the type return :: a -> IO a, which enables you to place pure values into IO. For any x, return x is an action which, when run, always produces x. This is why you have to end your do block with the return: username is a pure value you extracted from an action, and as such is only visible within the do block. You need to lift it into IO before the outside world can see it. The same is true of amount/tempamount.
And just for completeness's sake: there is some overarching theory behind this which ties it together. But it's not necessary at all for beginning Haskell programming. What I would recommend doing is structuring most of your code as pure functions which fold, spindle, and mutilate your data. Then construct a thin (as thin as possible) IO front layer which interacts with said functions. You'll be surprised how little IO you need!
1: It actually has a more general type, but that's not relevant for the moment.
Yeah, you're almost there but I think you want the signature:
investinput :: IO ([Char], Int)
... then from the calling function you can do something like:
main = do
(username, amount) <- investinput
....
I think you want to read tempamount rather than show though.
An IO function that produces a tuple would have type IO (a, b), in this case:
investinput :: IO ([Char], Int)
A signature of IO () -> ([Char], Int) would mean that the function takes a parameter of type IO () and produces a tuple from that, which is not what you want.
Generally there are no restrictions on the types an IO function (or a function in a different monad) can return, you can chose the types however you like.
The answer to your question about returning (String, Int) rather than IO (String, Int) is simple: you can't. Once you're in IO you're stuck there. That's part of what it means when people say that Haskell is a "pure" language.
What you want to do is similar to what you're already doing here with getLine. The type of getLine is IO String. When you write username <- getLine, you're in effect taking the String out of the IO String, but this is only possible because you're inside the do expression.
You can do exactly the same kind of thing with investinput as with getLine. Here's an example of how you could use investinput in your main function:
main = do
(name, amount) <- investinput
putStrLn $ name ++ " invested $" ++ show amount ++ "."
Since you mention liftM in a comment, here's a full working version that does the same thing using liftM and the reverse bind operator (=<<) instead of do notation:
import Control.Monad (liftM)
investinput :: IO (String, Int)
investinput = do
putStrLn "Enter Username : "
username <- getLine
putStrLn "Enter Invest Amount : "
amount <- liftM read getLine -- We can also use liftM to get rid of tempamount.
return (username, amount)
summary :: (String, Int) -> String
summary (name, amount) = name ++ " invested $" ++ show amount ++ "."
main = putStrLn =<< liftM summary investinput
This shows how you could use investinput with "another function which expects a tuple".