正如我一直在学习haskell,我已经享受纯粹的部分,但现在我蹒跚通过monadic和IO部分,并可能经历了一些人真正感到愤怒的语言。我解决了一个项目euler问题,我简单地想要一个可变数组,因为我必须经常通过索引来更新元素。我试过Vectors,但无法让它们工作,所以我尝试了Data.Array.IO。我可以读取和写入元素,但无法以我想要的方式在终端中显示数组。到目前为止,我有这个。显示IO阵列
test = do
arr <- newArray (1,10) 37 :: IO (IOArray Int Int)
a <- readArray arr 1
writeArray arr 1 64
b <- readArray arr 1
dispArray arr
return()
dispArray arr = do
(a,b) <- getBounds arr
printf "["
dispArray' arr a
printf "]\n"
where dispArray' arr i = do
(a,b) <- getBounds arr
if i < a || i > b
then return()
else do
v <- readArray arr i
print v
dispArray' arr (i+1)
这正如你所期望的输出中是这样的:
[64
37
37
37
37
37
37
37
37
37
]
但是,这是不方便的,我想这个[64,37,37,37....
这样。我见过类似toList
的功能,但我不想要这样的功能。我不想在每次显示时转换为列表。所以我想我需要使用printf
。所以我用printf " %s," (show v)
替换了print v
。但是这不能编译。我不知道为什么。我认为这将是因为print :: Show a => a -> IO()
和show :: Show a => a -> String
所以为什么它不会工作,因为%s
表示一个字符串?所以我接着打电话给对方。看看printf是否可以工作。
printf " %s," "hello"
print v
来编译和显示:
[ hello,64
hello,37
hello,37
hello,37
hello,37
hello,37
hello,37
hello,37
hello,37
hello,37
]
我为什么不能用show v
?为什么Haskell IO对初学者如此愤怒?
只是出于好奇,究竟是想用'的printf“%S”(编译时收到错误消息show v)'? – jwodder
'无法推断(PrintfType(m a0)) 由'dispArray'的歧义检查产生 我试过通过'::'添加类型,但是我觉得monads的类型是令人难以置信的神秘。 – DiegoNolan
Ps这是'ST'阵列的一个很好的用例。他们让你有一个可变的东西隐藏在一个纯粹的功能接口 – jozefg