2013-02-28 33 views
0

map2採用兩個列表ls1和ls2以及一個函數F,並返回一個與ls1和ls2中最短長度相同的列表,其中第i個元素是將F到LS1和LS2的第i個要素的結果(按順序)Haskell中的高階函數 - 「沒有......的實例」

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

當你得到這個工作時,你會發現結果是相反的。與'zipWith'不同的是,它確實可以做你認爲你的功能所做的事情。但是在你使用這個工具之前,只要你使用不同長度的列表,你也會遇到模式匹配錯誤。 – Ingo 2013-02-28 18:15:47

回答

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:我還應該指出,像你一樣以尾遞歸方式編寫這個函數並不是一個好主意。您編寫它的方式,在生成整個結果之前,您將無法訪問結果的第一個元素(結果列表的順序也會錯誤)。以更「幼稚」的非尾遞歸方式寫它會更懶,因此表現更好。這也會更簡單。

+0

啊,這是有道理的。你能提供一個寫這個函數的「天真」非尾遞歸方式嗎? – kachilous 2013-02-28 18:28:58

+1

看看zipWith函數。 – augustss 2013-02-28 18:31:41

+1

這個問題令人驚歎。謝謝! – kachilous 2013-02-28 18:41:52