我正在尝试模拟给定变量值的保存功能。最初我创建一个空白区域,然后当我想添加一个变量的值时,我在这个保存空间中更新了这个变量。
我希望能够有多个节省空间,并且有一个拥有自己的变量值。
我有以下代码
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
答案 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>