Haskell:Show用于以下类型的数据::*->*
我在为类型为的数据类型实现show实例时遇到问题 代码如下:Haskell:Show用于以下类型的数据::*->*,haskell,types,show,Haskell,Types,Show,我在为类型为的数据类型实现show实例时遇到问题 代码如下: data RMcom = LOAD Int | STORE Int | CLOAD Integer | CADD Integer | CSUB Integer | CMULT Integer | CDIV Integer | ADD Int | SUB Int | MULT Int | DIV Int | GOTO Integer | JZERO Integer |
data RMcom = LOAD Int | STORE Int | CLOAD Integer | CADD Integer |
CSUB Integer | CMULT Integer | CDIV Integer | ADD Int |
SUB Int | MULT Int | DIV Int | GOTO Integer | JZERO Integer |
END deriving (Eq, Show, Read)
type RMprog = Integer -> RMcom
type Register = Int -> Integer
data RMstate = State {progr :: RMprog, pc :: Integer, reg :: Register, maxReg :: Int}
这是一个注册表机器的模拟
现在我想自己为Show RMstate创建一个实例
通常我会这样做
instance Show RMstate where
show(State progr pc reg maxReg) = show(progr)++show(pc)++show(reg)++show(maxReg)
但是编译器希望有一个用于Show RMprog和Register的实例,但是如何实现呢
我能举例说明类型吗
提前感谢
RMProg
和寄存器
类型是函数。通常,函数不能以任何有趣的方式显示。您可以通过导入Text.Show.Functions
获得一些内容,但这可能不是您想要的
我建议您对这两种类型使用newtype
,并编写自己的Show
实例,这样做会更好
例如
newtype Register=寄存器(Int->Integer)
实例显示寄存器在哪里
show(Register f)=“Registers:++show[(i,fi)| i您可以执行以下操作
instance Show (x -> y) where
show _ = "<function>"
实例显示(x->y)其中
显示
然后代码就可以工作了……它不会让你有什么兴趣,但它会工作的
(这基本上就是导入Text.Show.Functions
所做的。)
就我个人而言,我赞成奥古斯都的建议,但这取决于你。明白了:
instance Show RMstate where
show (State prog i reg k) =
"\n"++"naechster Befehl: "++(show $ prog i)++"\n"++"Registerbelegungen: \n"++
(concat [ (show i)++": "++(show $ reg i)++"\n" | i <- [0..k]])
实例显示RMstate,其中
显示(状态程序i reg k)=
\n“++”naechster Befehl:“++(显示$prog i)++”\n“++”注册表项删除根:\n”++
(concat[(show i)++”:“++(show$reg i)+”+“\n”| i
我随意添加了maxProg::Integer
,因此我们知道在哪里停止RMprog
data RMstate = State {progr :: RMprog, pc :: Integer, reg :: Register,
maxReg :: Int, maxProg::Integer}
首先,让我们制作一个函数,一次显示一行函数,如RMprog
和Register
,例如
ghci> putStrLn $ showIndexed (+100) 1
1 101
像这样:
showIndexed :: (Show i, Show v) => (i -> v) -> i -> String
showIndexed f i = show i ++ '\t':show (f i)
现在我们可以通过将输出行粘在一起来显示RMstate
:
instance Show RMstate where
show s = unlines $
["","Program:"]
++ [showIndexed (progr s) i | i <- [0..maxProg s]]
++ ["","PC:\t"++show (pc s),"","Registers:"]
++ [showIndexed (reg s) i | i <- [0..maxReg s]]
example = State {progr=p, pc=3, reg=r, maxReg=15, maxProg=10} where
p = fromJust.flip lookup (zip [0..] [LOAD 3, STORE 2, CLOAD 1,
CADD 12, CSUB 4, CMULT 5,
CDIV 2, ADD 123, SUB 10,
MULT 5, DIV 2, GOTO 6,
JZERO 4, END])
r = fromJust . flip lookup (zip [0..] [3,4,3,5,6,5,2,5,7,2,4,5,672,5,56,3])
有没有可能在不需要额外导入的情况下,只在show函数中运行它?是的,您可以为show(a->b)
编写自己的实例。
showIndexed :: (Show i, Show v) => (i -> v) -> i -> String
showIndexed f i = show i ++ '\t':show (f i)
instance Show RMstate where
show s = unlines $
["","Program:"]
++ [showIndexed (progr s) i | i <- [0..maxProg s]]
++ ["","PC:\t"++show (pc s),"","Registers:"]
++ [showIndexed (reg s) i | i <- [0..maxReg s]]
example = State {progr=p, pc=3, reg=r, maxReg=15, maxProg=10} where
p = fromJust.flip lookup (zip [0..] [LOAD 3, STORE 2, CLOAD 1,
CADD 12, CSUB 4, CMULT 5,
CDIV 2, ADD 123, SUB 10,
MULT 5, DIV 2, GOTO 6,
JZERO 4, END])
r = fromJust . flip lookup (zip [0..] [3,4,3,5,6,5,2,5,7,2,4,5,672,5,56,3])
ghci> print example
Program:
0 LOAD 3
1 STORE 2
2 CLOAD 1
3 CADD 12
4 CSUB 4
5 CMULT 5
6 CDIV 2
7 ADD 123
8 SUB 10
9 MULT 5
10 DIV 2
PC: 3
Registers:
0 3
1 4
2 3
3 5
4 6
5 5
6 2
7 5
8 7
9 2
10 4
11 5
12 672
13 5
14 56
15 3