Haskell函数内不声明类型能否调用fromList 正确用法及报错解决
问题排查与解决方案
1. empty未定义报错修复
你当前定义的Config第二个字段是[Val](Val为Int别名),Haskell中列表类型的空值字面量为[],不存在内置的empty标识符,两种修复方式二选一即可:
- 直接在调用时替换
empty为[]:main = print (iexec (LOADI 5) (0, [], [])) - 手动定义
empty别名:在代码开头加一行empty :: [Val]; empty = []
2. 输出fromList格式的实现方案
你预期输出里的fromList []是Data.Map类型的默认Show输出格式,你当前的Config第二个字段是列表类型,默认Show输出为[],要达成目标效果,两种方案二选一即可:
方案1:修改Config类型为Map存储(推荐)
如果你本身就是要用Map实现内存存储,直接调整类型定义即可:
- 先导入Map模块:
import qualified Data.Map as Map
- 调整Config类型定义:
-- 第二个字段改为Map类型,键类型根据业务需求选择,这里假设内存地址为Int type Config = (Int, Map.Map Int Val, [Val])
- 函数实现无需修改,LOADI操作不需要修改内存的话直接透传即可:
iexec :: Instr -> Config -> Config iexec (LOADI x) (counter, memory, stack) = (counter + 1, memory, x : stack)
- 调用时传入Map空值:
main = print (iexec (LOADI 5) (0, Map.empty, []))
此时运行输出就是你预期的(1, fromList [], [5])
方案2:不修改存储类型,自定义Show实例
如果你不需要真的用Map存储,只是要输出格式匹配,给Config自定义Show实现即可:
type Val = Int type Config = (Int, [Val], [Val]) -- 自定义Show实例 instance Show Config where show (counter, memory, stack) = "(" ++ show counter ++ ", fromList " ++ show memory ++ ", " ++ show stack ++ ")"
此时你调用iexec (LOADI 5) (0, [], []),输出也会显示(1, fromList [], [5])
3. 原有代码报错原因说明
你尝试写Map.fromList memory报错有两个原因:
Map.fromList要求输入参数是[(键, 值)]格式的键值对列表,你传入的memory是[Val]单值列表,参数类型不匹配Map.fromList返回的是Map类型,和你原来Config定义里第二个字段的[Val]类型不匹配,触发类型错误
内容的提问来源于stack exchange,提问作者Ethan Gallagher
相关产品推荐
相关产品推荐

