存储变量valor模拟器

时间:2017-04-09 01:29:09

标签: haskell types

我正在尝试模拟给定变量值的保存功能。最初我创建一个空白区域,然后当我想添加一个变量的值时,我在这个保存空间中更新了这个变量。

我希望能够有多个节省空间,并且有一个拥有自己的变量值。

我有以下代码

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)

我的执行是这样的:

> 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>

所以这里的问题是函数更新不会“保存”所有变量值,只是最后一个。

正确的执行是:

> 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

1 个答案:

答案 0 :(得分: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>