我在为类型为
的数据类型实现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 |
END deriving (Eq, Show, Read)
type RMprog = Integer -> RMcom
type Register = Int -> Integer
data RMstate = State {progr :: RMprog, pc :: Integer, reg :: Register, maxReg :: Int}
它是Registermachine的模拟
所以现在我想自己为Show RMstate创建一个实例。
Normaly我会这样做
instance Show RMstate where
show(State progr pc reg maxReg) = show(progr)++show(pc)++show(reg)++show(maxReg)
但是编译器希望有一个Show RMprog和Register的实例,但是如何 我可以为类型创建一个实例吗?
提前致谢
答案 0 :(得分:10)
RMProg
和Register
类型是函数。一般来说,函数无法以任何有趣的方式显示。你可以通过导入Text.Show.Functions
获得一些东西,但它可能不是你想要的。
我建议您对这两种类型使用newtype
并编写自己的Show
实例,以便做得更好。
E.g。
newtype Register = Register (Int -> Integer)
instance Show Register where
show (Register f) = "Registers:" ++ show [(i, f i) | i <- [0..15] ]
答案 1 :(得分:1)
你可以做类似
的事情instance Show (x -> y) where
show _ = "<function>"
然后代码将工作 ...它不会显示您的任何兴趣,但它将工作。
(这基本上是导入Text.Show.Functions
所做的。)
就个人而言,我会从奥古斯都那里得到建议,但这取决于你。
答案 2 :(得分:1)
import Data.Maybe (fromJust)
我冒昧地添加了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])
看起来像:
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
答案 3 :(得分:0)
知道了:
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]])