如何使用map制作部分应用函数的列表?

时间:2017-05-11 08:55:34

标签: haskell functional-programming

我试图制作一个功能列表(以后用于zipwith),以便我有效地拥有[take 1,take 2,take 3],因此列表中的每个元素都应该具有{{1}类型}。

这是我尝试过的,感觉它应该是正确的。我不确定为什么我收到错误消息?

[Int] -> [Int]

2 个答案:

答案 0 :(得分:3)

首先,您的代码有效。但是函数无法获得show n。试试show id,最后会收到一条非常相似的错误消息。

但是在我们深入研究你的函数列表的应用之前,让我们看一下类型,看看你的逻辑是否合理。为简单起见,我们说1 :: Int。此外,\x -> take x只是take,因此我们可以使用map take [1..5]重现您的行为。现在我们在小型动荡中有以下参与者:

map    :: (a -> b           ) -> [a]    -> [b]
take   :: Int -> ([c] -> [c])                   -- explicit parentheses

现在我们将take插入map。在我们的mapa ~ Int由于take的第一个参数和b ~ [c] -> [c]。因此,我们有

map take :: [Int] -> [[c] -> [c]]

现在我们使用map take [1..5],它只删除上面一行中的类型:

map take        :: [Int] -> [[c] -> [c]]
[1..5]          :: [Int]
map take [1..5] ::          [[c] -> [c]]

我们已经完成了。我们最终的结果与您的错误消息完全相同。一切都结束了吗?的 是。您的代码没有任何问题。

但是,如前所述,[[c] -> [c]]无法显示。我们必须在您的列表中应用这些功能:

Prelude> map (\f -> f [1..10]) (map take [1..5])
[[1],[1,2],[1,2,3],[1,2,3,4],[1,2,3,4,5]]

答案 1 :(得分:1)

@kosmikus在评论中回答了您的问题,但是如果有人对此感兴趣,那么:t在控制台中会做什么。

以下是您想要的5个函数的列表,直接输入:

Prelude> :t [(take 1), (take 2), (take 3), (take 4), (take 5)]
[(take 1), (take 2), (take 3), (take 4), (take 5)] :: [[a] -> [a]]

将您的表达与map

一起使用
Prelude> :t map (\x -> take x) [1..5]
map (\x -> take x) [1..5] :: [[a] -> [a]]

顺便说一下,你也可以说:

Prelude> :t map take [1..5]
map take [1..5] :: [[a] -> [a]]

你不能做的是在GHCI控制台中呈现值本身,没有办法从列表到列表显示函数。 @kosmikus的:t技巧很不错。也就是说,您可以使用您的功能列表并查看它们的运行情况。例如:

Prelude> let takers = map take [1..5] in head(tail takers) [8,9,10,11]
[8,9]

将函数take 2应用于列表[8 9 10 11]