去除语法糖:在Haskell中列出理解 [英] Removing syntactic sugar: List comprehension in Haskell

查看:116
本文介绍了去除语法糖:在Haskell中列出理解的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



  [(i,j)| 

我可以在这个表达式中解除列表理解: i < - [1..4],j < - [i + 1..4]]



这是输出:

  [(1,2),(1,3),(1,4) ,(2,3),(2,4),(3,4)] 

我用地图,过滤器等等,写这段代码?

编辑

$ p
$ b

  [(i,j,k)| i < -  [1..6],j < -  [i + 1..6],k < -  [j + 1..6]] 
pre>

这是输出:

  [(1,2 ,3),(1,2,4),(1,2,5),(1,2,6),(1,3,4),(1,3,5),(1,3,6 ),(1,4,5),(1,4,6),(1,5,6),(2,3,4),(2,3,5),(2,3,6), (2,4,5-),(2,4,6),(2,5,6),(3,4,5),(3,4,6),(3,5,6),(4 ,5,6)] 


解决方案



列表理解(实际上,Monad理解)可以被解析为 do 表示法。

  do i<  -  [1..4] 
j < - [i + 1..4]
return(i,j)

可以像平常一样去除:

  [1..4]>> = \i  - > 
[i + 1..4]>> = \ j - >
return(i,j)

众所周知, a>> = \ x - >返回b fmap(\ x - > b)a 相同。所以,一个中间的desugaring步骤:

  [1..4]>> = \我 - > 
fmap(\ j - >(i,j))[i + 1..4]

对于列表,(>> =)= flip concatMap fmap = map

(flip concatMap)[1..4](\i - > map(\\ \\ j - >(i,j)[i + 1..4])

flip 只是简单地切换输入的顺序。

concatMap(\ i - > map(\ j - >(i,j))[i + 1..4])[1..4]

这就是你刚刚回答的结果。




第二个可以类似地解析成:

  concatMap(\i  - > ; 
concatMap(\ j - >
map(\ k - >
(i,j,k))
[j + 1..6])
[i + 1..6])
[1..6]


Can I unsugar list comprehension in this expression:

[(i,j) | i <- [1..4], j <- [i+1..4]]

This is the output:

[(1,2),(1,3),(1,4),(2,3),(2,4),(3,4)]

How can I, with map, filter and so on, write that piece of code?

edit

Here an other:

[(i,j,k) | i <- [1..6], j <- [i+1..6],k <- [j+1..6]]

This is the output:

[(1,2,3),(1,2,4),(1,2,5),(1,2,6),(1,3,4),(1,3,5),(1,3,6),(1,4,5),(1,4,6),(1,5,6),(2,3,4),(2,3,5),(2,3,6),(2,4,5),(2,4,6),(2,5,6),(3,4,5),(3,4,6),(3,5,6),(4,5,6)]

解决方案

List comprehensions (in fact, Monad comprehensions) can be desugared into do notation.

do i <- [1..4]
   j <- [i+1..4]
   return (i,j)

Which can be desugared as usual:

[1..4]   >>= \i ->
[i+1..4] >>= \j ->
return (i,j)

It is well known that a >>= \x -> return b is the same as fmap (\x -> b) a. So an intermediate desugaring step:

[1..4] >>= \i -> 
fmap (\j -> (i,j)) [i+1..4]

For lists, (>>=) = flip concatMap, and fmap = map

(flip concatMap) [1..4] (\i -> map (\j -> (i,j) [i+1..4])

flip simply switches the order of the inputs.

concatMap (\i -> map (\j -> (i,j)) [i+1..4]) [1..4]

And this is how you wind up with Tsuyoshi's answer.


The second can similarly be desugared into:

concatMap (\i ->
  concatMap (\j ->
    map       (\k ->
      (i,j,k))
    [j+1..6])
  [i+1..6])
[1..6]

这篇关于去除语法糖:在Haskell中列出理解的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆