You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么Haskell会将下一行代码识别为前一个函数的参数?

问题根源

你遇到的是Haskell do 表达式的语法规则问题:
如果你选择用显式大括号 {} 包裹do块的内容,必须用分号 ; 分隔每一条语句,否则Haskell不会通过换行/缩进识别语句边界,会把下一行的内容直接识别为上一行表达式的一部分。
你的代码中putStrLn ("test")和print ("works")之间没有分号,会被整体解析为putStrLn函数传入了三个参数:"test"、print、"works",和putStrLn :: String -> IO ()只接受一个字符串参数的类型完全不匹配,因此抛出对应的类型错误。

修复方案

有两种常用的修复方式:

方案1:保留显式大括号,补充分号分隔语句

main = do{
    putStrLn ("test");
    print ("works")
}

方案2:使用Haskell更通用的缩进敏感语法,省略大括号和分号

保证do块内的所有语句左对齐,缩进层级一致即可,这也是绝大多数Haskell代码采用的风格:

main = do
    putStrLn "test"
    print "works"

注:上述代码中去掉了参数外层多余的括号,Haskell中函数应用优先级最高,putStrLn "test"和putStrLn ("test")语义完全等价。

内容的提问来源于stack exchange,提问作者jessisogray

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 14:06:03