我正在尝试在SML中创建一个带有列表和int的函数,并返回一个小于int int * int list -> int list
的所有元素的列表。我编写了以下代码:
- fun less (e, L) =
= map (fn a => if a < e then a else []) L;
同样使用以下代码它也不起作用:
- fun less (e, L) =
= map (fn a => if a < e then a) L;
错误即时获取:
stdIn:22.15-22.38 Error: types of if branches do not agree [overload]
then branch: 'Z
else branch: 'Y list
in expression:
if a < e then a else nil
我认为问题出在其他部分,但我不知道该放什么工作,有人有什么建议吗?我应该使用map,foldl或foldr函数。
编辑:
- fun less (e, L) =
= let
= val acc = []
= in
= foldr (fn a => if a < e then a::acc else acc) acc L
= end;
仍然给我错误,出现以下错误:
stdIn:241.3-241.54 Error: operator and operand don't agree [overload]
operator domain: 'Z * 'Y -> 'Y
operand: 'X -> 'X list
in expression:
foldr (fn a => if <exp> < <exp> then <exp> :: <exp> else acc)
答案 0 :(得分:1)
错误消息很明确;由于a
的类型为int
而[]
的类型为'a list
,因此其类型不匹配。
问题是你为任务选择了错误的高阶函数。列表结构上的filter
最适合:
fun less (e, L) = filter (fn a => a < e) L
您可以使用递归显式实现less
,或使用foldl/foldr
累积已过滤的列表。但是,map
似乎与此无关。
修改强>
我将提供有关使用foldl/foldr
的提示。您从空列表开始作为累加器。只要该元素小于e
,就将一个元素添加到累加器;否则,返回累加器。
编辑2:
您忘记将acc
作为参数传递给lambda函数:
fun less (e, L) = foldr (fn (a, acc) => if a < e then a::acc else acc) [] L
let..in..end
部分是多余的,因为您只使用[]
作为累加器。