DrRacket入门学生语言中部门结构签名错误的修正咨询
解决BSL签名违规问题的调整方案
问题根源
Beginning Student Language(BSL)不支持通过signature定义自递归的类型别名(比如你写的DepartmentSig直接引用自身),这种写法会触发签名验证失败。需要改用BSL标准的递归数据定义格式描述部门结构,再为函数指定正确签名。
调整后的完整代码
(define-struct department (number-of-employees sub-departments)) ; A Department is a (make-department Number ListOfDepartment) ; interp. 一个部门包含自身员工数,以及下属子部门的列表 ; A ListOfDepartment is one of: ; - empty ; - (cons Department ListOfDepartment) ; interp. 部门的列表,要么为空,要么包含一个部门和另一个部门列表 (define department1 (make-department 10 (list (make-department 50 empty) (make-department 100 empty)))) (: sum-employees (Department -> Number)) ; 计算一个部门的总员工数(含所有子部门) (check-expect (sum-employees department1) 160) (define (sum-employees department) (+ (department-number-of-employees department) (sum-sub-departments (department-sub-departments department)))) (: sum-sub-departments (ListOfDepartment -> Number)) ; 计算一组子部门的总员工数 (check-expect (sum-sub-departments (department-sub-departments department1)) 150) (define (sum-sub-departments sub-departments) (if (empty? sub-departments) 0 (+ (sum-employees (first sub-departments)) (sum-sub-departments (rest sub-departments)))))
关键调整点
- 替换递归签名定义:
- 移除原
define DepartmentSig语句,改用BSL规范的代数数据类型定义:分别定义Department和ListOfDepartment,其中ListOfDepartment递归包含Department,Department的子部门字段类型为ListOfDepartment。
- 移除原
- 修正函数签名:
sum-employees签名改为(Department -> Number),直接使用数据定义中命名的类型。sum-sub-departments签名改为(ListOfDepartment -> Number),对应子部门列表的类型。
- 函数名优化(可选):将
number-of-employees-sub-department改为sum-sub-departments,更贴合函数功能语义。
这种写法完全符合BSL类型系统要求,递归数据定义会被编译器正确识别,不会再出现签名违规错误。
内容的提问来源于stack exchange,提问作者Antonia
相关产品推荐
相关产品推荐

