【问题标题】:Less-than function in Standard ML标准 ML 中的小于函数
【发布时间】:2012-04-09 11:23:09
【问题描述】:

我正在尝试在 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

我认为问题出在 else 部分,但我不知道该怎么做,有人有什么建议吗?我应该使用 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)

【问题讨论】:

    标签: list types map sml


    【解决方案1】:

    错误信息很清楚;由于a 的类型为int,而[] 的类型为'a list,它们的类型不匹配。

    问题是您为任务选择了错误的高阶函数。 List 结构上的filter 最适合这里:

    fun less (e, L) = filter (fn a => a < e) L
    

    您可以使用递归来显式实现less,或者使用foldl/foldr 来累积过滤列表。但是,map 在这里似乎无关紧要。

    编辑:

    我会提示使用foldl/foldr。您从空列表开始作为累加器。每当元素小于e 时,将元素添加到累加器;否则,返回累加器。

    编辑 2:

    您忘记在 lambda 函数中将 acc 作为参数传递:

    fun less (e, L) = foldr (fn (a, acc) => if a < e then a::acc else acc) [] L
    

    let..in..end 部分是多余的,因为您仅将[] 用作累加器。

    【讨论】:

    • 我应该使用 map、foldl 或 foldr 函数
    • @aizen92:我的意思是使用 :: 构造函数从元素 a::acc 和累加器 acc 中创建一个新列表 a::acc
    • 是的,我想出了这部分,但我的意思是什么是前置,与附加有什么区别?
    • @aizen92:它会改变元素的顺序。但是,建议使用它,因为:: 是 O(1) 而 @ 是 O(n) 左操作数列表的长度。
    • 我写了另一个代码,但我在第一篇文章中发布了空间,请检查它给我的错误
    猜你喜欢
    • 2016-01-19
    • 1970-01-01
    • 2015-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-23
    相关资源
    最近更新 更多