0

map2 接受两个列表,ls1 和 ls2 以及一个函数 F,并返回一个与 ls1 和 ls2 中最短的长度相同的列表,其中第 i 个元素是将 F 应用于 ls1 和 ls2 的第 i 个元素的结果(以该顺序)

module Map2 where

map2 lst1 lst2 f = map2_iter lst1 lst2 f len 0 []
    where len = (min (length lst1), (length lst2))
map2_iter (x:lst1) (y:lst2) f len i acc = if (i == len)
                      then acc
                      else let res = (f x y) in
                      map2_iter (lst1) (lst2) (f) (len) (i+1) ((res):acc)
map2_iter [] [] f len i acc = []

我收到以下错误

Map2.hs:3:20:
No instances for (Eq (Int -> Int), Num (Int -> Int, Int))
  arising from a use of `map2_iter'
Possible fix:
  add instance declarations for
  (Eq (Int -> Int), Num (Int -> Int, Int))
In the expression: map2_iter lst1 lst2 f len 0 []
In an equation for `map2':
    map2 lst1 lst2 f
      = map2_iter lst1 lst2 f len 0 []
      where
          len = (min (length lst1), (length lst2))

我不太确定这个错误是什么意思。任何人都可以提供任何帮助吗?

此外,这不是硬件,而是测试准备。

4

1 回答 1

4

错误消息告诉您无法比较Int -> Int函数是否相等,并且(Int -> Int, Int)元组不是数字。为什么要告诉你这个?因为len在您的代码中是一个(Int -> Int, Int)元组,并且您正在尝试比较它是否相等并将其视为一个数字。

那么len最终是如何成为一个数字的呢?(,)用于在 Haskell 中创建元组。写作(x,y)创建一个元组,其第一个元素是x,第二个元素是y。所以(min (length lst1), (length lst2))创建一个元组,其第一个元素是min (length lst1),第二个元素是length lst2。所以你最终得到一个包含一个函数(因为min (length lst1)计算为一个函数)和一个数字的元组。

PS:我还应该指出,像你一样递归地编写这个函数并不是一个好主意。按照您编写的方式,在生成整个结果之前,您将无法访问结果的第一个元素(结果列表的顺序也会错误)。以更“天真”的非尾递归方式编写它会更懒惰,因此性能更好。它也会更简单。

于 2013-02-28T18:06:35.733 回答