haskell
在real world haskell 里面看到一个例子. 就比葫芦画瓢的写了一遍.
结果从编译失败. 每个字母都检查了一下, 一模一样. 最后复制 例子 , 编译通过.
最后发现是缩进的问题. 代码如下:
正确的代码如下:
import System.IO
import Data.Char(toUpper)
main :: IO ()
main = do
inh <- openFile "input.txt" ReadMode
outh <- openFile "output.txt" WriteMode
mainloop inh outh
hClose inh
hClose outh
mainloop :: Handle -> Handle -> IO ()
mainloop inh outh =
do ineof <- hIsEOF inh
if ineof
then return ()
else do inpStr <- hGetLine inh
hPutStrLn outh (map toUpper inpStr)
mainloop inh outh
不正确的代码如下:
import System.IO
import Data.Char(toUpper)
main :: IO ()
main = do
inh <- openFile "input.txt" ReadMode
outh <- openFile "output.txt" WriteMode
mainloop inh outh
hClose inh
hClose outh
mainloop :: Handle -> Handle -> IO ()
mainloop inh outh =
do ineof <- hIsEOF inh
if ineof
then return ()
else do inpStr <- hGetLine inh
hPutStrLn outh (map toUpper inpStr)
mainloop inh outh
编译的时候提示:
[1 of 1] Compiling Main ( interactwith.hs, interactwith.o )
interactwith.hs:17:19:
The last statement in a 'do' construct must be an expression
谁能解释一下, haskell 的缩进是怎么回事? 应该怎么处理. 本来一个小程序, 结果折腾了一个上午. 非常感谢.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
你把do都拿出来单独一行,就会发现缩进很简单。
do是个语法糖,不单独写一行很多时候会导致缩进错误,并且会使代码参差不齐。
你这帖子回的就不严谨。。。
[ 本帖最后由 MMMIX 于 2009-1-22 12:59 编辑 ]
谢谢, 还是之前看书的时候不仔细造成的, 又看了一下规范,虽然只有几句话, 已经够用. 现在搞定了.
这种缩进方式, 可以让程序看起来, 更清晰 和 更严禁.
入门足够了。
{}, ; 只应该用在比较特殊的地方,例如很短的几个语句啥的。
Haskell 的 layout 在 YAHT 里面讲的也挺少的。
不过 Haskell 也支持 {} 和分号,因此可以和缩进混合使用。
Haskell 通过缩进(称为 layout) 确定代码的结构,layout 的作用和 C 的 {} 以及 ; 类似。在网上搜索点介绍资料看看。
btw,如果以前没有接触过 Haskell,不宜一开始就看 RWH,可以先看点入门资料,例如 Yet Another Haskell Tutorial 就不错。