Haskell 泛化问题(涉及列表理解)

发布于 2024-09-24 03:51:35 字数 441 浏览 1 评论 0原文

假设我想知道 (x, y) 平面上位于矩形 has 中的所有点。

我可以使用列表推导式进行计算,如下所示:

let myFun2D = [(x, y) | x <- [0..2], y <- [0..2]]

现在,如果我想对 (x, y, z) 空间完成相同的操作,我可以采用相同的方法并执行

let myFun3D = [(x, y, z) | x <- [0..2], y <- [0..2], z <- [0..2]]

以下操作 :如何将其推广到任意数量的维度?如果是,怎么办?

let myFunGeneralized = ?

谢谢

Let's say I want to know all the points on a (x, y) plane that are in the rectangle has.

I can calculate that using List Comprehensions, this way:

let myFun2D = [(x, y) | x <- [0..2], y <- [0..2]]

Now, if I want to accomplish the same for a (x, y, z) space, I can go the same way and do:

let myFun3D = [(x, y, z) | x <- [0..2], y <- [0..2], z <- [0..2]]

Is there a way to generalize this for any number of dimensions? If yes, how?

let myFunGeneralized = ?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

羁绊已千年 2024-10-01 03:51:35

不幸的是,由于 [(a,a)][(a,a,a)] 等属于不同类型,因此您无法编写一个函数来表示所有其中。

无论如何,一般来说你可以使用

Prelude> let x = [0..2]
Prelude> import Control.Applicative 
Prelude Control.Applicative> (,,) <
gt; x <*> x <*> x
[(0,0,0),(0,0,1),(0,0,2),(0,1,0),(0,1,1),(0,1,2),(0,2,0),(0,2,1),(0,2,2),(1,0,0),(1,0,1),(1,0,2),(1,1,0),(1,1,1),(1,1,2),(1,2,0),(1,2,1),(1,2,2),(2,0,0),(2,0,1),(2,0,2),(2,1,0),(2,1,1),(2,1,2),(2,2,0),(2,2,1),(2,2,2)]

如果你想要一个 [[a]] 代替,有一个非常简单的函数:

Prelude> sequence (replicate 3 x)
[[0,0,0],[0,0,1],[0,0,2],[0,1,0],[0,1,1],[0,1,2],[0,2,0],[0,2,1],[0,2,2],[1,0,0],[1,0,1],[1,0,2],[1,1,0],[1,1,1],[1,1,2],[1,2,0],[1,2,1],[1,2,2],[2,0,0],[2,0,1],[2,0,2],[2,1,0],[2,1,1],[2,1,2],[2,2,0],[2,2,1],[2,2,2]]

or (感谢 sdcvvc)

Prelude> import Control.Monad
Prelude Control.Monad> replicateM 3 x
[[0,0,0],[0,0,1],[0,0,2],[0,1,0],[0,1,1],[0,1,2],[0,2,0],[0,2,1],[0,2,2],[1,0,0],[1,0,1],[1,0,2],[1,1,0],[1,1,1],[1,1,2],[1,2,0],[1,2,1],[1,2,2],[2,0,0],[2,0,1],[2,0,2],[2,1,0],[2,1,1],[2,1,2],[2,2,0],[2,2,1],[2,2,2]]

Unfortunately, because [(a,a)] and [(a,a,a)] etc are of different types, you can't write one function to represent all of them.

Anyway, in general you could use

Prelude> let x = [0..2]
Prelude> import Control.Applicative 
Prelude Control.Applicative> (,,) <
gt; x <*> x <*> x
[(0,0,0),(0,0,1),(0,0,2),(0,1,0),(0,1,1),(0,1,2),(0,2,0),(0,2,1),(0,2,2),(1,0,0),(1,0,1),(1,0,2),(1,1,0),(1,1,1),(1,1,2),(1,2,0),(1,2,1),(1,2,2),(2,0,0),(2,0,1),(2,0,2),(2,1,0),(2,1,1),(2,1,2),(2,2,0),(2,2,1),(2,2,2)]

If you want an [[a]] instead, there is a very simple function for this:

Prelude> sequence (replicate 3 x)
[[0,0,0],[0,0,1],[0,0,2],[0,1,0],[0,1,1],[0,1,2],[0,2,0],[0,2,1],[0,2,2],[1,0,0],[1,0,1],[1,0,2],[1,1,0],[1,1,1],[1,1,2],[1,2,0],[1,2,1],[1,2,2],[2,0,0],[2,0,1],[2,0,2],[2,1,0],[2,1,1],[2,1,2],[2,2,0],[2,2,1],[2,2,2]]

or (thanks sdcvvc)

Prelude> import Control.Monad
Prelude Control.Monad> replicateM 3 x
[[0,0,0],[0,0,1],[0,0,2],[0,1,0],[0,1,1],[0,1,2],[0,2,0],[0,2,1],[0,2,2],[1,0,0],[1,0,1],[1,0,2],[1,1,0],[1,1,1],[1,1,2],[1,2,0],[1,2,1],[1,2,2],[2,0,0],[2,0,1],[2,0,2],[2,1,0],[2,1,1],[2,1,2],[2,2,0],[2,2,1],[2,2,2]]
忘你却要生生世世 2024-10-01 03:51:35

列表到元组问题可以使用 Template Haskell 来处理,如下所示(运行 ghci -XTemplateHaskell ):

> import Language.Haskell.TH
> let x = [0..2]
> let tt n l = listE [tupE [[|l!!i|] | i <- [0..(n-1)]] | l <- sequence $ replicate n l ]
> $(tt 2 x)
[(0,0),(0,1),(0,2),(1,0),(1,1),(1,2),(2,0),(2,1),(2,2)]
> $(tt 3 x)
[(0,0,0),(0,0,1),(0,0,2),(0,1,0),(0,1,1),(0,1,2),(0,2,0),(0,2,1),(0,2,2),(1,0,0),(1,0,1),(1,0,2),(1,1,0),(1,1,1),(1,1,2),(1,2,0),(1,2,1),(1,2,2),(2,0,0),(2,0,1),(2,0,2),(2,1,0),(2,1,1),(2,1,2),(2,2,0),(2,2,1),(2,2,2)]

The list to tuple problem could be handled with Template Haskell like this (running ghci -XTemplateHaskell):

> import Language.Haskell.TH
> let x = [0..2]
> let tt n l = listE [tupE [[|l!!i|] | i <- [0..(n-1)]] | l <- sequence $ replicate n l ]
> $(tt 2 x)
[(0,0),(0,1),(0,2),(1,0),(1,1),(1,2),(2,0),(2,1),(2,2)]
> $(tt 3 x)
[(0,0,0),(0,0,1),(0,0,2),(0,1,0),(0,1,1),(0,1,2),(0,2,0),(0,2,1),(0,2,2),(1,0,0),(1,0,1),(1,0,2),(1,1,0),(1,1,1),(1,1,2),(1,2,0),(1,2,1),(1,2,2),(2,0,0),(2,0,1),(2,0,2),(2,1,0),(2,1,1),(2,1,2),(2,2,0),(2,2,1),(2,2,2)]
凉栀 2024-10-01 03:51:35

您可以使用这样的内容:

myFun :: Integer -> [[Integer]] -- Param: number of dimensions
myFun dim = snd $
  until ((== 0) . fst) --recursive build your tuple
  (\(d,lst) -> (pred d,[x:l|x <- [0..2],l <- lst]))
  (dim,[[]])

这将为您提供一个点列表列表,您可以假设所有这些子列表都具有相同的长度。它应该像这样工作:

> myFun 0
  []
> myFun 1
  [[0],[1],[2]]
> myFun 2
  [[0,0],[0,1],[0,2],[1,0],[1,1],[1,2],[2,0],[2,1],[2,2]]

You could use something like this:

myFun :: Integer -> [[Integer]] -- Param: number of dimensions
myFun dim = snd $
  until ((== 0) . fst) --recursive build your tuple
  (\(d,lst) -> (pred d,[x:l|x <- [0..2],l <- lst]))
  (dim,[[]])

This will give you a list of point lists, you can assume that all these sublists have the same length. It should work like this:

> myFun 0
  []
> myFun 1
  [[0],[1],[2]]
> myFun 2
  [[0,0],[0,1],[0,2],[1,0],[1,1],[1,2],[2,0],[2,1],[2,2]]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文