从其他环境返回变量

时间:2019-06-05 00:18:26

标签: mit-scheme

我正在尝试在其他环境的范围内返回变量。 我目前拥有的是

(define make-empty-env
   (lambda()
      (make-top-level-environment)
   )
)

,当您从解释程序调用它时会创建一个新环境 即(定义环境(make-empty-env))

如果我在“ env”中将变量“ a”定义为15,则我的目标是通过从用户初始环境调用的函数返回该值。

类似

(apply-env env'v)输出-> env范围内变量v的值。 v可以在user-initial-environment中未定义,但是如果变量在env中存在,仍会返回一个值。

我尝试过:

(define apply-env
   (lambda (env v)
       (eval (+ v 0) env)
   )
)

无效,因为调用函数时传递了符号'v。我的主要问题是我不知道如何传递符号并将其像函数中的变量一样对待。这是一项作业,功能提示为:

  

(apply-env env v)

     

返回环境env中的变量v的值。

     

以下是对apply-env的一些调用:

     

在test-env中,a = 1,b = 2

     

(apply-env test-env'a)   1

     

(apply-env test-env'b)   2

我是计划的新手,所以我可能会缺少一些基本知识,非常感谢任何指针或帮助。

2 个答案:

答案 0 :(得分:1)

据我所知,环境变量的设计实现取决于您。由于这是一个家庭作业问题,因此我假设您可以按照自己喜欢的任何方式进行操作(我认为)。

所以可以说,您希望将环境变量设置为a,它是2个元素的列表的列表。

env -> ((var1,val1),(var2,val2),......,(varn.valn))

E.g.

env -> ((a,1),(b,2),(c,3))

现在,当您要初始“创建”环境时,您只需要调用返回初始环境为的函数。现在我们的环境变量env只是一个空列表'()。你可以做一个这样的功能

(define (make-empty-env)
    (lambda ()
        '()
    )
)

现在可以在env中添加,删除和更新变量,您可以为基础数据结构实现carcdrin-env?之类的功能


;;; cdr like function for env
(define (cdr-env env)
    (cdr env)
)

;;; car like function for env
(define (car-env)
    (list (car env))
)

;;; Returns boolean for v in env
(define (in-env? env)
    (cond
        ((null? env)    ; If env is empty then v doesnt exist in env
            #f
        )
        ((equal? v (car (car env))) ; If first element of the first list in env matches with v 
            #t
        )
        (else       ; Recursive step to find if v is in the remaining enviornment env
            (in-env? v (cdr env))
        )
    )
)

使用这些功能,您可以相对轻松地实现env的插入,检索和更新功能。


;;; Update the value variable v to val in env. This function assumes that you are calling it in the insert-env function
(define (update-env v val env)
    (cond 
        ((null? env)
            '()
        )
        ((equal? v (car (car env)))
            (append (cdr env) (list (list v val)))
        )
        (else
            (append 
                (update-env v val (cdr env)) 
                (list (list (car (car env)) (car (cdr (car env)))))
            )
        )
    )
)


;;; add a variable-value pair (v,val) to env, also checks if variable already exists in pair. If so then updates it
(define (insert-env v val env)
    (cond 
        ((in-env? v env)
            (update-env v val env)
        )
        (else  ; Add to env the 2 element list (v val)
            (append env (list (list v val)))
        )
    )
)

;;; Gets the value of variable v or returns an error message
(define apply-env
    (lambda (env v)
        (cond 
            ((null? env)    ; If env is empty then no variablles exist for the name v
                (error "appply-env: found empty enviroment")
            )
            ((equal? (car (car env)) v) ; First element of the first list is v [matching var found in env]
                (car (cdr (car env))) ; Second element of that list is value of v
            )
            (else       ; Else look for v in the rest of the env list
                (apply-env (cdr env) v) 
            )
        )
    )
)
  

注意:   您对env的上述函数的实现方式将取决于您选择如何实现将变量绑定存储在env中的数据结构   您可以使用任何喜欢的数据结构。例如。二叉树。堆栈,队列等

希望这会有所帮助!

答案 1 :(得分:1)

问题在于添加未分阶段进行。考虑以下使用准引用的方法:

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.savedfences);

        listViewFences = findViewById(R.id.fencesListView);
        fenceList = new ArrayList<>();

        fenceAdapter = new FenceAdapter(FenceActivity.this, R.layout.list_layout_fences, fenceList);
        listViewFences.setAdapter(fenceAdapter);

        showFencesFromDatabase();
    }

   public void showFencesFromDatabase() {

        dataBaseHelper = new DataBaseHelper(this);
        Cursor cursor = dataBaseHelper.getAllData();
        if (cursor.moveToFirst()) {
            do {
                fenceList.add(new Fence(cursor.getInt(0), cursor.getDouble(1), cursor.getDouble(2), cursor.getInt(3)));
            } while (cursor.moveToNext());
        }
        cursor.close();
        notifyDataSetChanged();

        if(fenceList.size() > 0){
            findViewById(R.id.emptyElement.setVisibility(View.GONE);
            fenceList.setVisibility(View.VISIBLE); 
        }else{
            findViewById(R.id.emptyElement.setVisibility(View.VISIBLE);
            fenceList.setVisibility(View.GONE); 
        }

    }

准引号等效于(define apply-env (lambda (env v) (eval `(+ ,v 0) env) ) )