Haskell递归树函数改造:传递额外Int参数报错求助
解决Haskell中
map与多参数函数结合的问题 这个问题我之前写递归树处理代码时也踩过坑,核心是没摸透Haskell的函数柯里化特性和map的参数要求~
先给你拆解下报错原因:map的类型是(a -> b) -> [a] -> [b],它只接受一个单参数函数和一个列表。你修改后的identity是Tree -> Int -> Tree,本质上是柯里化后的Tree -> (Int -> Tree)——也就是说,当你只给它传一个Tree参数时,它会返回一个等待接收Int的函数,但map需要的是能直接把Tree转换成Tree的函数(也就是Tree -> Tree类型),所以直接写map identity xs amount肯定会报错。
这里有两种简洁的解决方法:
方法1:用lambda表达式固定参数
手动创建一个匿名函数,把amount作为固定值,只接收Tree作为输入,这样就符合map需要的单参数函数类型了:
identity :: Tree -> Int -> Tree identity (Leaf mi) amount = Leaf (transformNote mi amount) identity (Node mi xs) amount = Node (transformNote mi amount) (map (\tree -> identity tree amount) xs)
方法2:利用flip函数调整参数顺序
Haskell的flip函数可以交换多参数函数的前两个参数顺序。原来的identity是Tree -> Int -> Tree,用flip转换后会变成Int -> Tree -> Tree,这时传入amount就会得到一个Tree -> Tree的函数,刚好适配map的要求:
import Data.Function (flip) -- 若未导入该模块需要添加这句 identity :: Tree -> Int -> Tree identity (Leaf mi) amount = Leaf (transformNote mi amount) identity (Node mi xs) amount = Node (transformNote mi amount) (map (flip identity amount) xs)
两种方法都能解决问题,第一种更直观易懂,第二种则是利用Haskell的函数特性让代码更简洁,你可以根据自己的习惯选择~
内容的提问来源于stack exchange,提问作者Marcel
相关产品推荐
相关产品推荐

