Reputation: 15
I'm trying to use the function setElem in Haskell to update the Matrix, but seems the new value does not stay in the matrix. Is there a way to use this function to go around this problem?
I'm new with Haskell and what I need is to set a new value in the matrix and then show the matrix updated.
setElem :: a -> (Int, Int) -> Matrix a -> Matrix a
My code:
import Data.Matrix
import System.Random
import System.IO
import Data.Array
table_game = matrix 20 20 $ \(i,j)-> "#"
inputCoordenadas = do
putStrLn "Digite -1 -1 para encerrar: "
putStrLn "Digite a coordenada X: "
coord_x <- getLine
putStrLn "Digite a coordenada Y: "
coord_y <- getLine
let x = (read coord_x :: Int)
let y = (read coord_y :: Int)
if(coord_x == "-1" && coord_y=="-1") then do
putStrLn ("Encerrando o jogo...")
return ()
else do
print $ setElem "X" (2,2) table_game
print table_game
inputCoordenadas
main = do
putStrLn "Iniciar jogo|1 - Encerrar jogo|0: "
buffer <- getLine
let n = (read buffer :: Int)
if n==0 then do
putStrLn "Encerrando o jogo"
return ()
else do
print table_game
inputCoordenadas
Upvotes: 1
Views: 213
Reputation: 26161
Haskell uses pure functions. Pure functions can not modify anything out of their context and prevent side effects. What you are trying is a sin in Haskell. Setting a global variable and trying to mutate it is a no no.
You are basically expected to structure your code such that the inputCoordenadas
function takes a table-game (tg
in my code below), prints it, modifies it and returns a new table-game. With minimal change your code should be like
import Data.Matrix
import System.Random
import System.IO
import Data.Array
inputCoordenadas tg = do
print tg
putStrLn "Digite -1 -1 para encerrar: "
putStrLn "Digite a coordenada X: "
coord_x <- getLine
putStrLn "Digite a coordenada Y: "
coord_y <- getLine
let x = (read coord_x :: Int)
let y = (read coord_y :: Int)
if(coord_x == "-1" && coord_y=="-1") then putStrLn "Encerrando o jogo..."
else inputCoordenadas $ setElem "X" (x,y) tg
main = do
putStrLn "Iniciar jogo|1 - Encerrar jogo|0: "
buffer <- getLine
let n = (read buffer :: Int)
if n==0 then putStrLn "Encerrando o jogo"
else inputCoordenadas $ matrix n n (\(i,j) -> "#")
Upvotes: 1
Reputation: 60463
Haskell does not have mutable variables. The simplest (least abstract) way to do this is to add a parameter to your function:
inputCoordinadas tab = do
....
let newTab = setElem "X" (x,y) tab
inputCoordinadas newTab
So each time the function is called, it is called with the "current" table. When it calls itself, it passes an updated table.
There are fancier ways to do this but this solution is also fine and relatively common even among those who know the fancy ways.
Upvotes: 1