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
相关产品推荐
相关产品推荐

