【问题标题】:DrRacket type mismatch error in eval function using the substitution model使用替换模型的 eval 函数中的 DrRacket 类型不匹配错误
【发布时间】:2019-06-07 14:27:23
【问题描述】:

我已经实现了语言“ROL”,现在我正在尝试扩展该语言以支持 fun 和 call 我正在尝试在替换模型中实现它。

这是我的 eval 函数代码(请注意,此代码在没有 fun 和 call 的情况下工作得很好。所以问题一定出在这两个实现上

(: eval : RegE -> RES)
;; evaluates RegE expressions by reducing them to bit-lists
(define (eval expr)
  (cases expr
    [(Reg right) (RegV right)]
    [(Bool b) (RES_Bool b)]
    [(Id name) (error 'eval "free identifier: ~s" name)]
    [(And left right) (reg-arith-op bit-and  (eval left ) (eval right) )]
    [(Or left right) (reg-arith-op bit-or (eval left )  (eval right) )]
    [(Shl E1) (RegV (shift-left (RegV->bit-list (eval E1))))]
    [(Maj E1) (RES_Bool (majority? (RegV->bit-list (eval E1))))]
    [(Geq E1 E2) (RES_Bool (geq-bitlists? (RegV->bit-list (eval E1)) (RegV->bit-list (eval E2))))]
    [(With bound-id named-expr bound-body)
       (eval (subst bound-body
                    bound-id
                    (Reg (RegV->bit-list(eval named-expr)))))]
    [(Fun bound-id bound-body) expr]
    [(Call fun-expr arg-expr)
       (let ([fval (eval fun-expr)])
         (cases fval
           [(Fun bound-id bound-body)
            (eval (subst bound-body
                   bound-id
                   (eval arg-expr)))]
           [else (error 'eval "`call' expects a function, got: ~s"
                              fval)]))]
    [(If E1 E2 E3) (if (RegV->boolean (eval E1)) (eval E2) (eval E3))]



))

这是我的 sunst 函数:

(define (subst expr from to)
  (cases expr
    [(Reg g) expr]
    [(Bool g) expr]
    [(And left right)(And (subst left from to)(subst right from to))]
    [(Or left right)(Or (subst left from to)(subst right from to))]
    [(If bool ifBody elseBody) (If (subst bool from to) (subst ifBody from to) (subst elseBody from to))]
    [(Maj left)(Maj (subst left from to))]
    [(Geq left right)(Geq (subst left from to)(subst right from to))]
    [(Shl left)(Shl (subst left from to))]
    [(Id name) (if (eq? name from) to expr)]
    [(With bound-id named-expr bound-body)
           (if (eq? bound-id from)
               expr
               (With bound-id
                     named-expr
               (subst bound-body from to)))]
    [(Call left right) (Call (subst left from to) (subst right from to))]
    [(Fun bound-id bound-body)
         (if (eq? bound-id from)
           expr
           (Fun bound-id (subst bound-body from to)))]))

我收到了错误:

Type Checker: type mismatch
  expected: RegE
  given: RES in: fval
. Type Checker: type mismatch
  expected: RegE
  given: RES in: (eval arg-expr)
. Type Checker: type mismatch
  expected: RES
  given: Fun in: (cases expr ((Reg right) (RegV right)) ((Bool b) (RES_Bool b)) ((Id name) (error (quote eval) "free identifier: ~s" name)) ((And left right) (reg-arith-op bit-and (eval left) (eval right))) ((Or left right) (reg-arith-op bit-or (eval left) (eval right))) ((Shl E1) (RegV (shift-left (RegV->bit-list (eval E1))))) ((Maj E1) (RES_Bool (majority? (RegV->bit-list (eval E1))))) ((Geq E1 E2) (RES_Bool (geq-bitlists? (RegV->bit-list (eval E1)) (RegV->bit-list (eval E2))))) ((With bound-id named-expr bound-body) (eval (subst bound-body bound-id (Reg (RegV->bit-list (eval named-expr)))))) ((Fun bound-id bound-body) expr) ((Call fun-expr arg-expr) (let ((fval (eval fun-expr))) (cases fval ((Fun bound-id bound-body) (eval (subst bound-body bound-id (eval arg-expr)))) (else (error (quote eval) "`call' expects a function, got: ~s" fval))))) ((If E1 E2 E3) (if (RegV->boolean (eval E1)) (eval E2) (eval E3))))
. Type Checker: Summary: 3 errors encountered in:
  fval
  (eval arg-expr)
  (cases expr ((Reg right) (RegV right)) ((Bool b) (RES_Bool b)) ((Id name) (error (quote eval) "free identifier: ~s" name)) ((And left right) (reg-arith-op bit-and (eval left) (eval right))) ((Or left right) (reg-arith-op bit-or (eval left) (eval right))) ((Shl E1) (RegV (shift-left (RegV->bit-list (eval E1))))) ((Maj E1) (RES_Bool (majority? (RegV->bit-list (eval E1))))) ((Geq E1 E2) (RES_Bool (geq-bitlists? (RegV->bit-list (eval E1)) (RegV->bit-list (eval E2))))) ((With bound-id named-expr bound-body) (eval (subst bound-body bound-id (Reg (RegV->bit-list (eval named-expr)))))) ((Fun bound-id bound-body) expr) ((Call fun-expr arg-expr) (let ((fval (eval fun-expr))) (cases fval ((Fun bound-id bound-body) (eval (subst bound-body bound-id (eval arg-expr)))) (else (error (quote eval) "`call' expects a function, got: ~s" fval))))) ((If E1 E2 E3) (if (RegV->boolean (eval E1)) (eval E2) (eval E3))))
>

我的数据类型是:

(define-type RegE
[Reg Bit-List]
[Xor RegE RegE]
[And RegE RegE]
[Or RegE RegE]
[Shl RegE]
[Id Symbol]
[With Symbol RegE RegE]
[Bool Boolean]
[Geq RegE RegE]
[Maj RegE]
[If RegE RegE RegE]
[Fun Symbol RegE]
[Call RegE RegE])

和:

(define-type RES
[RES_Bool Boolean]
[RegV Bit-List])

我可以看到对于(let ([fval (eval fun-expr) 执行(eval fun-expr) 将返回RES,我猜这可能是问题所在,还有其他方法可以记下它吗?任何帮助将不胜感激..

【问题讨论】:

  • 只是为了确保:您正在使用 eopl ?
  • 不,我正在使用 pl
  • 好的,Barzilays 语言。你能发布你的数据类型吗?
  • 是的,刚刚做了

标签: racket eval call substitution


【解决方案1】:

关键问题是您希望如何在运行时表示函数。 eval的定义是:

(: eval : RegE -> RES)
;; evaluates RegE expressions by reducing them to bit-lists
(define (eval expr)
  (cases expr
  ...
  [(Fun bound-id bound-body) expr]
  ...

评估(Fun bound-id bound-body) 的结果需要是一个RES。 也许将 RES 扩展为:

(define-type RES
    [RES_Bool Boolean]
    [RegV Bit-List]
    [FunV Symbol RegE])

然后让eval 返回一个(FunV bound-id bound-body)

在Call的评估中,你需要切换到

     (cases fval
       [(FunV bound-id bound-body)

因为fval 是一个RES。

【讨论】:

  • 刚刚试了一下,第一个错误确实修复了,但是第二个和第三个错误还是一样..
  • 对不起,我的错误,它给了我类型检查器:预期类型不匹配:RegE 给定:RES in:(eval arg-expr) 在我将 fun 更改为 [(Fun bound-id bound- body) (FunV bound-id bound-body)]
  • 当您评估 (eval arg-expr) 时,您将获得 RES。但是 subst 需要 RegE。所以把(eval arg-expr)改成arg-expr
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-02-05
  • 1970-01-01
  • 2017-06-23
  • 1970-01-01
  • 2019-02-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多