Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
无点Haskell中基于映射的乘法表_Haskell_Pointfree - Fatal编程技术网

无点Haskell中基于映射的乘法表

无点Haskell中基于映射的乘法表,haskell,pointfree,Haskell,Pointfree,在Haskell中,我定义了一个乘法表生成器函数,如下所示: multTable :: [[Int]] multTable=map (\b -> map (b*) [1..12]) [1..12] 哪个输出 [[1,2,3,4,5,6,7,8,9,10,11,12], [2,4,6,8,10,12,14,16,18,20,22,24], ...[12,24,36,48,60,72,84,96,108,120,132,144]] …如果你眯起眼睛,这看起来像是1..12的乘法表。到现在为

在Haskell中,我定义了一个乘法表生成器函数,如下所示:

multTable :: [[Int]]
multTable=map (\b -> map (b*) [1..12]) [1..12]
哪个输出

[[1,2,3,4,5,6,7,8,9,10,11,12],
[2,4,6,8,10,12,14,16,18,20,22,24],
...[12,24,36,48,60,72,84,96,108,120,132,144]]
…如果你眯起眼睛,这看起来像是1..12的乘法表。到现在为止,一直都还不错。。。现在我试着让它没有任何意义,认为它应该很容易与组成。因此,我采取了一些小的步骤,我相信我已经走到了一半,因为我可以做到这一点:

map ($ 4) $ map (*) [1..12]
…这给了我:

[4,8,12,16,20,24,28,32,36,40,44,48]
看看这个,第二个映射给出了[a->a],这里是一个函数列表,它将值1到12乘以某个数字。第一个映射评估这些函数中的每一个,为它们提供值4,然后生成[4,8..]行

我不一定期望无点版本更简短,更简洁,甚至更可读。作为一名Haskell的新手,我只是想了解它是如何实现的。

有一个叫做hackage的工具,它对你有极大的帮助(另请参阅)。它将创建以下版本:

multTable = map (flip map [1..12] . (*)) [1..12]
我们怎么去那里?好吧,让我们稍微移动操作符,并尝试在函数上应用
flip
,直到得到类似的结果:

multTable = map (\b -> map (b*) [1..12])           [1..12] 
          = map (\b -> map ((*) b) [1..12])        [1..12] -- change to prefix notation
          = map (\b -> flip map [1..12] ((*) b)    [1..12] -- flip map
          = map (\b -> flip map [1..12] . (*) $ b) [1..12] -- associativity
          = map (flip map [1..12] . (*))           [1..12] -- eta-reduction
注意,我们只需要关注
\b->map(b*)[1..12]

尽管如此,无点版本感觉有点做作。毕竟,您需要一个表,要创建一个表:列表理解:

multTable = [[x * y | x <- [1..12]] | y <- [1..12]]

multTable=[[x*y | x在对Zeta回答的评论中,他建议重新实现您的代码:

do
    x <- [1..12]
    return $ do
        y <- [1..12]
        return (x * y)
现在我突然想到,
m>=\x->return(fx)
fmap fm
是一样的,所以上面的代码实际上只需要
Functor而不需要
Monad
。所以这让我想知道什么是“Functor的
do
-符号”可能看起来像,以及它将如何去糖化。定义
for=flip fmap
,我认为它可能看起来是如何去糖化的:

for [1..12] $ \x ->
for [1..12] $ \y ->
x*y
(希望您能看到与desugared
do
-符号的相似之处。)在任何情况下,如果将其无点化,都会得到非常漂亮的结果:

for [1..12] $ for [1..12] . (*)

刚接触哈斯克尔的人似乎爱上了无点模式。爱情是盲目的,你会从中解脱出来。顺便说一句,这里有一个不错的(不是无点)版本:
[[x*y | x@BenjaminHodgson如果他对它感兴趣,为什么不让他来?看看你能把一些编程技术或概念发展到什么程度很有趣。不管它最终是否实用,这都不一定重要。泽塔的回答在逐步细化方面很有启发性,从我的原创开始,以无点形式结束。丹尼尔s的答案有一个吸引人的风格,我觉得非常直观。两个答案都很好。谢谢。
do
符号变体没有列表理解好:
do{x“函子理解”版本特别好:
let for=flip-fmap-in for[1..12]$\x->for[1..12]$\y->x*y
。如果您将其指向自由,您将获得[1..12]的
,[1..12]的$(*)
这在我看来很漂亮。@DanielWagner:你想添加这个作为答案吗?它看起来真的很漂亮。我不小心在
fmap
中省略了“f”,它仍然适用于你提供的其余表达式。这个
翻转
映射的
(或
fmap
)作为
for
对我来说非常有意义。这是一个非常有趣的见解。@devgeezer是的,对于列表,
fmap=map
。很高兴你喜欢它。
for [1..12] $ for [1..12] . (*)