【问题标题】:New to SML / NJ. Adding numbers from a list of listsSML / NJ 的新手。从列表列表中添加数字
【发布时间】:2013-09-18 11:39:53
【问题描述】:

定义一个函数,用于计算 a 中所有整数的和 给定的整数列表列表。没有“if-then-else”或任何辅助 函数。

我是函数式编程的新手,在使用 SML 的正确语法方面遇到了麻烦。为了解决这个问题,我尝试使用模式匹配创建一个函数,该函数只添加列表的前两个元素。完成这项工作后,我将使用递归来添加其余元素。不过,我什至似乎无法编译这个简单的函数。

fun listAdd [_,[]] = 0
|   listAnd [[],_] = 0
|   listAnd [[x::xs],[y::ys]] = x + y;

【问题讨论】:

    标签: functional-programming sml smlnj


    【解决方案1】:
    fun listAdd [] = 0
      | listAdd ([]::L) = listAdd L
      | listAdd ((x::xs)::L) = x + listAdd (xs::L)
    

    应该做你想做的。

    此外,您的函数的部分问题似乎是您在不同的子句中为函数赋予了不同的名称(listAdd 和 listAnd)。

    【讨论】:

    • 如何调用这个函数?我试过 listAdd ([4,5],[3,5]);并得到类型错误
    • 那是因为 ([4,5],[3,5]) 是一对列表,而不是列表的列表,就像你说的那样。尝试在 [[4,5],[3,5]] 上调用它。如果您想要一对列表的总和,而不是列表列表,那么您将需要一个不同的函数。如果是这种情况,我可以更新答案以反映这一点。
    【解决方案2】:

    为了简单起见,我想说你可能想要这个:

    fun listAdd : (int * int) list -> int list
    

    现在,我将其简单地定义为 unzip 函数的抽象:

    fun listAdd ls :
        case ls of 
            [] => 0
          | (x,y) :: ls' => (x + y) + (listAdd ls')
    

    我认为列出两个单独的列表是没有意义的。只需获取一个包含整数乘积的列表。如果你必须构建它,你可以调用 zip 函数:

    fun zip xs ys :
        case xs, ys of
            [], [] => []
          | xs, _ => []
          | _, ys => []
          | x::xs', y::ys' => (x,y) :: (zip xs' ys')
    

    一般来说,如果你真的想要,你可以写一个更抽象的 general 类型的函数:

    fun absProdList : ((`a * `b) -> `c) -> (`a * `b) list -> `c list
    

    这个功能很简单:

    fun absProdList f ls =
        case l of 
            [] => []
          | (x,y) :: ls' => (f (x,y)) :: (absProdList f ls')
    

    这个函数是你提到的addList 函数的超类型。只需定义一个匿名函数即可将您的 addList 重新创建为:

    fun addList' ls =
        absProdList (fn (x,y) => x + y) ls
    

    如您所见,定义泛型类型函数可以通过适当组合以下方式对作为通用类型替换的函数的特定调用变得更加容易和优雅:Currying、高阶函数和匿名函数。

    【讨论】:

      【解决方案3】:

      您可能不希望将 int list list 作为输入,而只是希望使用 int list * int list(一对 int 列表)。除此之外,您的函数似乎返回数字而不是数字列表。为此,您将使用递归。

      fun listAdd (x::xs, y::ys) = (x + y) :: listAdd (xs, ys)
        | listAdd ([], _) = []
        | listAdd (_, []) = [] (* The last two cases can be merged *)
      

      您可能想从第一页开始阅读有关函数式编程的书。如果您想要免费的,请选择 Riccardo Pucella 的 Notes on Programming in SML/NJ

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-08-30
        • 2018-03-19
        • 2014-05-23
        • 2016-02-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-07-06
        相关资源
        最近更新 更多