如何在haskell中使用map函数?

时间:2017-10-27 03:50:52

标签: dictionary haskell

我正在尝试使用map来返回列表列表。但我不断收到错误。我知道map接受一个函数,然后使用该函数。但我不断收到错误。

map (take 3) [1,2,3,4,5]

这应该返回[[1,2,3],[2,3,4],[3,4,5]],但它会返回此错误

<interactive>:6:1: error:
• Non type-variable argument in the constraint: Num [a]
  (Use FlexibleContexts to permit this)
• When checking the inferred type
    it :: forall a. Num [a] => [[a]]

它击中null是为什么?

1 个答案:

答案 0 :(得分:7)

让我们看一下错误消息的确切内容。

map (take 3) [1, 2, 3, 4, 5]

map的类型签名是

map :: (a -> b) -> [a] -> [b]

因此需要从ab的函数,并返回从[a][b]的函数。在您的情况下,函数是take 3,它接受​​一个列表并返回一个列表。因此ab都是[t]。因此,map的第二个参数应为[[t]],列表列表。现在,Haskell查看了第二个参数,并发现它是一个数字列表。所以它说&#34;我如何将一个数字列入一个列表?&#34; Haskell并不知道有什么好办法,所以它抱怨说它不知道任何类型Num [t]

现在,至于你打算做什么,我相信评论中提到了这一点。 tails函数 1 获取一个列表并返回该列表的所有尾部列表。所以

tails [1, 2, 3, 4, 5]
-- ==> [[1, 2, 3, 4, 5], [2, 3, 4, 5], [3, 4, 5], [4, 5], [5], []]

现在您可以将take函数应用于每个参数。

map (take 3) (tails [1, 2, 3, 4, 5])
-- ==> [[1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5], [5], []]

糟糕!我们有一些我们不想要的额外价值。我们只想要包含三个元素的值。因此,让我们过滤我们不想要的。 filter采用谓词(这只是一种奇特的说法&#34;一个返回布尔值的函数)和一个列表,并返回一个只包含满足谓词的元素的列表。我们想要的谓词是一个获取列表并返回该列表是否包含三个元素的谓词。

\x -> ...           -- We want only the lists
\x -> length x ...  -- whose length
\x -> length x == 3 -- is exactly equal to 3

这就是我们的功能。现在我们将其传递给filter

filter (\x -> length x == 3) (map (take 3) (tails [1, 2, 3, 4, 5]))
-- ==> [[1, 2, 3], [2, 3, 4], [3, 4, 5]]

[1]请注意,您可能需要import Data.List才能获得tails功能。