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

Haskell使用sortBy排序列表运行报print输入解析错误

报错原因

该解析错误由Haskell缩进规则不匹配导致:

  • do块内所有平级语句必须保持一致的缩进层级
  • let绑定附属的where子句必须和对应let关键字缩进对齐,否则解析器会判定let绑定提前结束,后续代码因缩进位置非法无法解析。

原代码中where缩进深度大于let关键字,解析器读取到where时认为compareLastNames函数定义已结束,后续的print语句缩进和do块内首个语句的缩进层级不匹配,直接抛出解析错误。

修复方案

方案1:调整缩进对齐

将where关键字调整到和let相同的缩进层级,同时保证do块内所有平级语句缩进一致即可:

import Data.List

main :: IO ()
names = [("Tatsunori", "Ono"), ("Kishore", "Palanisamy"), ("Calder", "Hosgood"), ("Yiling", "Zhuang")]

main = do
  let compareLastNames name1 name2 = if lastName1 > lastName2
                                       then GT
                                       else if lastName1 < lastName2
                                             then LT
                                             else EQ
    where lastName1 = snd name1
          lastName2 = snd name2
  print (sortBy compareLastNames names)

方案2:将辅助定义移入let内部

直接在let块内完成辅助变量定义,完全规避where子句的缩进坑,代码逻辑更清晰:

import Data.List

main :: IO ()
names = [("Tatsunori", "Ono"), ("Kishore", "Palanisamy"), ("Calder", "Hosgood"), ("Yiling", "Zhuang")]

main = do
  let compareLastNames name1 name2 = 
        let lastName1 = snd name1
            lastName2 = snd name2
        in compare lastName1 lastName2
  print (sortBy compareLastNames names)

简化写法

导入Data.Ord模块的comparing工具函数,可以直接基于元组的第二个元素(姓氏)生成比较规则,不需要手写判断逻辑:

import Data.List
import Data.Ord (comparing)

main :: IO ()
names = [("Tatsunori", "Ono"), ("Kishore", "Palanisamy"), ("Calder", "Hosgood"), ("Yiling", "Zhuang")]

main = print $ sortBy (comparing snd) names

运行上述代码后,会输出按姓氏升序排列的姓名列表:

[("Calder","Hosgood"),("Tatsunori","Ono"),("Kishore","Palanisamy"),("Yiling","Zhuang")]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 13:09:16