0

I am trying the simulate a save functionality for the value of a given variables. Initially I create an empty space and then when I want to add a value of a variable, I do an update of this variable in this save space.

I want to be able to have the possibility of multiple save space, and with one to have its own variable values.

I have the following code

type Variable = String
type Val = Int

type Store = Variable -> Val

init :: Store
init = (\x -> 0)

fetch :: Store -> Variable ->Val
fetch store variable = store variable


update :: Store -> Variable -> Val -> Store
update s v val = (\x -> if x == v then val else init v)

And the execution i make is this:

> Main> s1 = init
> *Main> s2 = update s1 "x" 10
> *Main> s2 = update s2 "y" 30
> *Main> fetch s2 "x" 
0
> *Main> fetch s2 "y" 
30
> *Main>

So the problem here is that the function update does not "saves" all the variables values, just the last one.

A correct excution would be this:

> Main> s1 = init
> *Main> s2 = update s1 "x" 10
> *Main> s2 = update s2 "y" 30
> *Main> s2 = update s2 "z" 50
> *Main> fetch s2 "x" 
10
> *Main> fetch s2 "y" 
30
> *Main> fetch s2 "z" 
50
> *Main> fetch s2 "w" 
0
K. A. Buhr
  • 45,621
  • 3
  • 45
  • 71
Jordi
  • 3
  • 1
  • `s v`, not `init v`. Turn on -Wall to be warned that `s` is unused. Was this way of saving your idea? – Gurkenglas Apr 09 '17 at 01:38
  • 1
    http://stackoverflow.com/questions/993124/does-haskell-have-variables –  Apr 09 '17 at 03:21
  • You are redefining `s2` in GHCi as a recursive function. You clearly don't intend to do that. Try instead `s1 = init ; s2 = update s1 "x" 10 ; s3 = update s2 "y" 30 ; s4 = update s3 "z" 50` using different variables every time. – chi Apr 09 '17 at 07:59

1 Answers1

0

As has been pointed out in the comments, you actually have two problems. You can't reuse "s2" the way you are because in an expression like this:

let s2 = ... something that includes s2 ...

the s2 on the right hand side is not the "old" value of s2. Instead, it's a recursive reference to the new s2 you are defining. This would cause an infinite loop if your code were correct, but you have a second bug. Your update function adds a new variable definition to init, not to supplied previous store s, so it doesn't "update" anything and it never uses the old s it's been passed. Instead, redefine your update like this:

update :: Store -> Variable -> Val -> Store
update s v val = (\x -> if x == v then val else s x)

(Note that you want s x, not s v -- x is the variable you're trying to look up, and if it doesn't match v, then you want to pass it along to the old store s.) Now it will work, as long as you don't reuse any store variable names:

*Main> s1 = Main.init  -- use "Main." to avoid conflict w/ Prelude.init
*Main> s2 = update s1 "x" 10
*Main> s3 = update s2 "y" 30
*Main> fetch s3 "x"
10
*Main> fetch s3 "y"
30
*Main> 
K. A. Buhr
  • 45,621
  • 3
  • 45
  • 71