scheme中的强制操作

前文为了实现同样类型的通用型计算法,采取了计算包的方式。
但还未考虑过,如果是不同类型的数据,该如何进行计算?例如有理数和实数、整数和复数?这之间如何调和。
scheme给出一个“强制”操作用来解决此类问题。

点击查看代码
(define (scheme-number->complex n)(make-complex-from-real-imag (contents n) 0))
(put-coercion 'scheme-number 'complex scheme-number->complex)
(define (apply-generic op. args)(let ((type-tags (map type-tag args)))(let ((proc (get op type-tags)))(if proc(apply proc (map contents args))(if (= (length args) 2))(let ((type1 (car type-tags))(type2 (cadr type-tags))(a1 (car args))(a2 (cadr args)))(let ((t1->t2 (get-coercion type1 type2))(t2->t1 (get-coercion type2 type1)))(cond (t1->t2 (apply-generic op (t1->t2 a1) a2))(t2->t1 (apply-generic op a1 (t2->t1 a2)))(else (error "No method for these types" (list op type-tags))))))(erroe "No method for these types" (list op type-tags))))))
将不同类型的数据强制为同类数据,之后的计算过程与前文类似。 练习2.81 Louis注意到,在两个参数类型实际相同的情况下,apply-generic也可能试图去做参数间的强制。由此他推论需要在强制表格中加入一些过程,将每个参数强制为他们本身的类型。 a)如果真的采用了强制自身的过程,那么在条共apply-generic过程时,各参数类型都为scheme或者complex,而表格中找不到相应的操作,此时会发生什么情况? 答:该过程会陷入死循环,操作不存在时apply-generic会不断调用自身。 b)Louis真的纠正了有关同样类型参数的强制问题吗? 答:并未。加入强制自身的过程后,本检索不到相关操作就会报错退出,此时会产生t1->t2、t2->t1的不断循环,程序进入死循环。 c)修改apply-generic,使之不会试着蛆强制两个同样类型的参数。 答:增加一个判断即可,当检索不到proc且参数类型相同时直接报错。
点击查看代码
define (apply-generic op. args)(let ((type-tage (map type-tag args)))(let ((proc (get op type-tags)))(if proc(apply proc (map contents args))(if (= (length args) 2))(let ((type1 (car type-tags))(type2 (cadr type-tags))(a1 (car args))(a2 (cadr args)))(if (equal? type1 type2)(error "No method for these types" (list op type-tags))(let ((t1->t2 (get-coercion type1 type2))(t2->t1 (get-coercion type2 type1)))(cond (t1->t2 (apply-generic op (t1->t2 a1) a2))(t2->t1 (apply-generic op a1 (t2->t1 a2)))(else (error "No method for these types" (list op type-tags)))))))(error "No method for these types" (list op type-tags))))))
练习2.82 请阐述一种方法,设法推广apply-generic,以便处理多个参数的一般性情况下的强制问题。一种可能策略是试着将所有参数都强制到第一个参数的类型,而后试着强制到第二个参数的类型,以此类推。请给出一个例子说明这种策略还不够一般。
点击查看代码
(define (attach-tag type-tag contents)(cons type-tag contents))
(define (type-tag datum)(if (pair? datum)(car datum)(error "Bad tagged datum" datum)))
(define (contents datum)(if (pair? datum)(cadr datum)(error "Bad tagged datum" datum)))
(define (all-the-same? items)(cond ((null? items) #t))((= (length items) 1) #t)(else (if (equal? (car items)(cadr items))(all-the-same? (cdr items))#f)))
(define (for-each-map ops items)(if (null? ops)'()(cons ((car ops)(car items))(for-each-map (cdr ops)(cdr items)))))
(define (map-all-or-false op items)(if (null? items)'()(let ((first-ret (op (car items))))(if first-ret (let ((second-ret (map-all-or-false op (cdr items))))(if second-ret(cons first-ret second-ret)#f))#f))))
(define (get-coercion-list type-tags to-type)(define (identity x) x)(map-all-or-false (lambda (type) (if (equal? type to-type)identity(get-coercion type to-type))) type-tags))
(define (try-coercion-list type-tags args)(define (try-single-coercion type-tags args to-type)(if (null? to-type)#f(let ((coercion-list (get-coercion-list type-tags to-type)))(if coercion-list(for-each-map coercion-list args)(try-single-coercion type-tags args (cdr to-type))))))(if (all-the-same? type-tags?)#f(try-single-coercion type-tags args (car type-tags))))
(define (apply-generic-list op args)(let ((type-tags (map type-tag args)))(let ((proc (get op type-tags)))(if proc(apply proc (map contents args))(let ((coercion-args (try-coercion-args type-tags args)))(if coercion-args(apply-generic-list op coercion-args)(error "No method for these types -- APPLY-GENERIC" (list op type-tags)))))))) 
(define (apply-generic op . args)(apply-generic-list op args))
该方案只能做到直接转换,如果A、B、C三种类型可以A->B、B->C,理论上应该可以A->B->C,但目前的设计只能做到A->C

练习2.83 假定在设计一个通用型算数包,处理类型塔,请为每个类型设计一个过程,它能将该类型的对象提升到塔的上面一层。请说明如何安装一个通用的raise操作,使之能对各个类型工作。

点击查看代码
(define (raise x)(let ((raise-proc (get 'raise (list (type-tag x)))))(if raise-proc(raise-proc (contents x))#f)))
(define (install-rasie-package)(put 'raise '(integer)(lambda (x) (make-ractional x 1)))(put 'raise '(ractional)(lambda (x) (make-real (/ (number x) (denom x)))))(put 'raise '(real)(lambda (x) (make-complex-from-real-imag x 0))))

练习2.84 利用练习2.83里的raise操作修改apply-generic过程,使它能通过逐层提升的方法将参数强制到同样的类型。

点击查看代码
(define (raise-to-type x type)(let ((x-type (type-tag x)))(if (equal? x-type type)x(let ((x-raise (raise x)))(if x-raise(raise-to-type x-raise type)#f)))))
(define (apply-generic op . args)(let ((type-tags (map type-tag args)))(let ((proc (get op type-tags)))(if proc(apply proc (map contents args))(if (and (= (length args) 2) (not (equal? (car type-tags) (cadr type-tags))))(let ((a1 (car args))(a2 (cadr args)))(let ((a1-raise (raise-to-type a1 (type-tag a2))))(if a1-raise(apply-generic op a1-raise a2)(let ((a2-raise (raise-to-type a2 (type-tag a1))))(if a2-raise(apply-generic op a1 a2-raise))(error "No method for these types" (list op type-tags))))))(error "No method for these types" (list op type-tags)))))))

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1169961.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

springboot光影视频(11715)

有需要的同学,源代码和配套文档领取,加文章最下方的名片哦 一、项目演示 项目演示视频 二、资料介绍 完整源代码(前后端源代码SQL脚本)配套文档(LWPPT开题报告)远程调试控屏包运行 三、技术介绍 Java…

基于Matlab实现双线性变换法设计(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码

基于Matlab实现双线性变换法设计(设计源文件万字报告讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码 BW型、CB型、椭圆型高通、带通数字滤波器。 附带实验报告。

2026年GEO优化软著办理源头优选,高效合规服务商 - 源码云科技

2026年GEO优化软著办理源头优选,高效合规服务商2026年的AI营销赛道,GEO优化早已不是可选项而是必答题。随着生成式搜索引擎占据近六成线上流量入口,企业想在AI搜索中站稳脚跟,选对和直接决定流量获取效率。源码云(…

凤希AI伴侣:从科幻梦想到生产力革命-2026年1月16日

思考与发现今天身体不适,但休息时思考了一个核心问题:工作与纯粹的娱乐在思维模式上是冲突的。作为拥有超过25年开发经验的程序员,我真正的兴趣在于运营、市场和企业品牌建设。AI的出现,完美地弥补了我的“短板”——将想法系统化…

基于MATLAB的单相接地故障自动重合闸仿真系统设计(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码

基于MATLAB的单相接地故障自动重合闸仿真系统设计(设计源文件万字报告讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码 本设计包括设计报告,仿真工程。 目前我国的远距离输配电系统(220~1000kv)架空线路上&#…

2026最新三亚跟团游旅行社推荐!专业三亚跟团游服务机构权威测评,资质与体验双优助力海岛度假 - 品牌推荐2026

引言 随着国内旅游市场的全面复苏,三亚凭借独特的热带滨海资源持续成为度假首选目的地。然而,市场上旅行社资质参差不齐、服务标准不一等问题,让消费者在选择时面临诸多困扰。据中国旅游协会最新发布的《2026旅游服…

Python爬虫与物流轨迹:为何官方API才是明智之选

当您需要为系统添加物流轨迹查询功能时,技术团队首先会面临一个关键抉择:是自主研发Python爬虫从各家快递公司网站“抓取”数据,还是通过一个统一的平台,如快递鸟的官方API进行“对接”?这个看似是“自主研发”与“调用…

Python爬虫与物流轨迹:为何官方API才是明智之选

当您需要为系统添加物流轨迹查询功能时,技术团队首先会面临一个关键抉择:是自主研发Python爬虫从各家快递公司网站“抓取”数据,还是通过一个统一的平台,如快递鸟的官方API进行“对接”?这个看似是“自主研发”与“调用…

深度解析 MySQL 与 MCP 集成:从环境构建到 AI 驱动的数据交互全流程(2026版)

深度解析 MySQL 与 MCP 集成:从环境构建到 AI 驱动的数据交互全流程(2026版) 在2026年的AI生态中,MCP(Model Context Protocol,模型上下文协议)作为标准化LLM(大语言模型&#xff0…

大模型赋能政务:核心能力与应用场景全解析(值得收藏)

文章探讨了大模型技术在政务领域的应用价值。大模型具备自然语言理解与生成、多任务泛化、推理决策等核心能力,通过智能服务升级、精准治理、协同办公和决策升级四大场景赋能政务转型。政府部门需构建专用算力底座、创新应用场景并保障安全伦理,实现从&q…

2026最新三亚旅游公司推荐!品质服务与多元体验并重,权威榜单助您畅享椰岛风情 - 品牌推荐2026

引言 随着旅游消费持续升级,三亚作为国内热门度假目的地,市场对旅游服务的专业性、个性化和安全性提出了更高要求。然而,行业中仍存在服务标准不一、产品同质化等问题,给消费者选择带来困扰。据中国旅游协会最新发…

考虑阶梯式碳交易机制与电制氢的综合能源系统热电优化(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码

考虑阶梯式碳交易机制与电制氢的综合能源系统热电优化(设计源文件万字报告讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码 核心算法。完整复现碳交易市场下的能源系统优化调度,包含阶梯式碳交易定价、电制氢两阶段过程(电解…

C语言中%d、%f、%p、%c、%s、%的代表意义

在C语言中,printf()(以及scanf()等函数)使用的 % 字母 称为格式说明符(或格式占位符),它们告诉函数应该以什么格式来输出(或输入)对应的参数。 以下是你问到的几个最常用格式说明符…

谷歌《Agents》白皮书揭秘AI从“能说“到“会做“的智能体革命

谷歌《Agents》白皮书介绍了AI智能体的核心概念,它是一种能自主行动的AI,由模型、推理框架和工具调用能力构成。相比传统AI,智能体能实时更新知识、管理会话状态并自主决策。通过上下文学习、检索式学习和微调学习三种方法可提升其能力。未来…

谷歌《Agents》白皮书揭秘AI从“能说“到“会做“的智能体革命

谷歌《Agents》白皮书介绍了AI智能体的核心概念,它是一种能自主行动的AI,由模型、推理框架和工具调用能力构成。相比传统AI,智能体能实时更新知识、管理会话状态并自主决策。通过上下文学习、检索式学习和微调学习三种方法可提升其能力。未来…

数据库存储引擎与索引技术深度解析

数据库存储引擎概述 数据库存储引擎(Storage Engine)是数据库管理系统(DBMS)中负责数据存储、检索和管理的核心组件。它决定了数据如何在磁盘或内存中组织、如何处理读写操作,以及如何支持事务、并发控制等特性。不同…

一文读懂基因过表达细胞系基因 | 过表达细胞系构建全流程解析 | 稳定转染技术 | 载体设计优化

技术概述与基本原理 基因过表达细胞系是通过分子克隆技术将外源基因导入宿主细胞,并实现稳定遗传和持续表达的工程化细胞系统。这一技术体系为现代生命科学研究提供了关键工具,能够实现特定基因的持续高表达,为基因…

大模型时代的技术跃迁:30-40岁技术骨干如何借AI浪潮巩固核心竞争力

在技术快速迭代的今天,30-40岁的技术骨干正站在职业发展的关键十字路口。作为经验丰富的Java/Python开发者、软件工程师或架构师,你们已经建立了坚实的技术基础,但同时也面临着前所未有的挑战:技术栈需要不断深化,AI/大…

2026最新深圳出口退税服务机构推荐!专业高效退税方案助力企业减负增效,深圳出口退税服务公司权威推荐 - 品牌推荐2026

引言 随着全球贸易格局加速调整,出口企业对退税服务的专业性、时效性与合规性要求显著提升。据国家税务总局最新数据显示,2025年全国出口退税平均办理时长已压缩至6个工作日,但企业仍面临政策理解不深、流程繁琐、风…

MiniMax、智谱上市背后:中国AI产业链的连锁反应正在到来

2026年初这轮上市所打开的,并不是一个简单的融资窗口,而是一种新的产业运行方式。模型公司获得持续投入能力,上游获得长期订单预期,下游获得更可控的技术伙伴。产业链开始从试水状态,转向围绕长期能力建设的协同阶段。…