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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With