Haskell基于三类指令的简易加法复制程序开发问询
实现基于自定义指令集的Haskell程序(加法与复制功能)
我来帮你梳理一下如何实现这个基于三类指令的Haskell程序,包括核心的加法和复制功能。先从指令集的定义开始,一步步搭建逻辑:
指令集与核心类型定义
首先,我们先明确给定的指令类型和程序类型的Haskell定义:
-- 指令类型定义:三类操作 data Instruction = DEL {box :: Int} | ADD {box :: Int} | JEQ {box1 :: Int, box2 :: Int, jumpTo :: Int} deriving (Eq, Show) -- 程序是指令的列表 type Program = [Instruction]
每个指令的作用:
DEL b:清空编号为b的box(将其值设为0)ADD b:将编号为b的box的值加1JEQ b1 b2 j:如果boxb1和boxb2的值相等,则跳转到程序的第j条指令继续执行(指令从1开始计数)
另外注意:用户输入的初始值列表从box1开始,box0可以作为临时变量使用(默认初始值可设为0)。
核心功能实现
接下来我们实现两个要求的功能:复制和加法,基于上面的指令集编写对应的程序。
1. 复制功能:将boxA的值复制到boxB
思路:先清空目标boxB,然后循环检查boxA和boxB是否相等——如果不等,就给boxB加1,重复这个过程直到两者值相等,此时boxB的值就和boxA的初始值一致了。
对应的程序实现:
-- 复制box1的值到box2的程序 copyBox1ToBox2 :: Program copyBox1ToBox2 = [ DEL 2 -- 1: 清空目标box2 , JEQ 1 2 4 -- 2: 若box1与box2相等,跳转到第4条(终止) , ADD 2 -- 3: 给box2加1,回到第2条继续检查 , JEQ 0 0 4 -- 4: 空跳转(终止执行,因为后续无指令) ]
2. 加法功能:将box1与box2的值相加,结果存入box3
思路:利用临时box0,分两步累加:
- 先清空结果box3和临时box0,循环将box1的值“转移”到box3(每次临时box0加1,结果box3加1,直到临时等于box1)
- 重置临时box0为0,再用同样的方式将box2的值累加到box3中
对应的程序实现:
-- 将box1+box2的结果存入box3的程序 addBox1Box2ToBox3 :: Program addBox1Box2ToBox3 = [ DEL 3 -- 1: 清空结果box3 , DEL 0 -- 2: 清空临时box0 , JEQ 1 0 7 -- 3: 若box1等于box0,跳转到第7条(处理box2) , ADD 3 -- 4: 结果加1 , ADD 0 -- 5: 临时加1 , JEQ 0 0 3 -- 6: 跳回第3条继续循环 , DEL 0 -- 7: 重置临时box0为0 , JEQ 2 0 11 -- 8: 若box2等于box0,跳转到第11条(终止) , ADD 3 -- 9: 结果加1 , ADD 0 -- 10: 临时加1 , JEQ 0 0 8 -- 11: 跳回第8条继续循环 ]
程序解释器实现
为了运行上面的程序,我们需要一个解释器来模拟指令的执行流程。这个解释器会接收初始box状态、程序,输出最终的box状态:
-- 解释器核心函数:参数依次为当前指令索引(从1开始)、当前box状态、待执行程序 execute :: Int -> [Int] -> Program -> [Int] execute idx boxes program | idx < 1 || idx > length program = boxes -- 指令索引超出范围,终止执行 | otherwise = case program !! (idx - 1) of -- 转换为Haskell列表的0索引 DEL b -> execute (idx + 1) (updateBox b 0 boxes) program ADD b -> execute (idx + 1) (updateBox b (boxes !! b + 1) boxes) program JEQ b1 b2 j -> if boxes !! b1 == boxes !! b2 then execute j boxes program else execute (idx + 1) boxes program where -- 更新指定box的值(box编号为0-based) updateBox :: Int -> Int -> [Int] -> [Int] updateBox b newVal = take b ++ [newVal] ++ drop (b + 1)
测试示例
我们可以用以下示例测试功能:
- 复制测试:初始box状态为
[0,5,0](box0=0,box1=5,box2=0),执行复制程序后box2的值变为5testCopy = execute 1 [0,5,0] copyBox1ToBox2 -- 输出:[0,5,5] - 加法测试:初始box状态为
[0,3,4,0](box0=0,box1=3,box2=4,box3=0),执行加法程序后box3的值变为7testAdd = execute 1 [0,3,4,0] addBox1Box2ToBox3 -- 输出:[0,3,4,7]
内容的提问来源于stack exchange,提问作者vincentko37




