Reputation: 455
Hi I have these functions:
i_am_at::String->String
i_am_at place =
place
at::String-> (String, String)
at place =
case place of
"bedroom" -> ("fly", "light switch")
"den" -> ("flyswatter", "light switch")
main::IO()
main = do
putStrLn "Enter place"
p <- getLine :: IO String
i_am_at p
I want to write a function "take" that takes an argument "item" and calls the i_am_at function which returns a string "place", and then calls the "at" function with the string returned by the i_am_at function, and then checks if the item is a light switch when place is bedroom, then store it into a array and return it. But, if item is fly then don't store it. Similarly, if place is den and the item is either from the two then store it into that array. I am doing something like this:
take::String->String[],IO()
take item =
plc = i_am_at
| plc == "bedroom" && item == "light switch" && item not present in list y already (I don't know how to write this condition)
y = item
| plc == "bedroom" && item == "fly" && item not present in list y already (I don't know how to write this condition)
= putStrLn "You cannot take that"
| plc == "den" && item == "flyswatter" && item not present in list y already (I don't know how to write this condition)
y = item
| plc == "den" && item == "light switch" && item not present in list y already (I don't know how to write this condition)
y = item
| if item present in list y already
= putStrLn "You already have it"
| Otherwise = putStrLn "Item is not here"
return y
Could somebody help me fix this function. y is a list in this function, but I don't know how to store values in it. I also don't know how can we have a return type that's returning a value as well and printing it out too. I also don't know if the statement plc=i_am_at
is correct or not. How to make this work?
Upvotes: 0
Views: 105
Reputation: 52049
In a pure functional language like Haskell you emulate mutable state with the following recipe:
World
)World -> World
(or, perhaps World -> IO World
if you need to perform IO. The function creates a new world value from an existing one.Example: Let's say your world consists of just a list of items (Strings):
type World = [String]
To remove an item you would write a function like:
removeItem :: String -> World -> IO World
removeItem item world = do
if elem item world
then do putStrLn "Item removed."
return $ delete item world
else do putStrLn "No such item - " ++ item
return world
Then you can remove two items with:
removeTwoItems a b world = do
world1 <- removeItem a world
world2 <- removeItem b world
return world2
There are advanced mechanisms (like the State
monad) to help you with these kinds of patterns, but this is essentially what is going on.
An more complete example showing how to integrate this patterns into an application:
look :: World -> IO World
look w = do
putStrLn $ "You see these items here: " ++ show w
return w
loop w = do
words <- fmap words getLine
case words of
("quit":_) -> return ()
("look":_) -> do w' <- look; loop w'
("remove":item:_) -> do w' <- removeItem item w; loop w'
_ -> do putStrLn "huh?"; loop w
main = do
let world0 = ["chair", "bucket"] -- the initial world
loop world0
Upvotes: 2