簡體   English   中英

Haskell泛化問題(涉及列表推導)

[英]Haskell generalizing problem (involving list comprehensions)

比方說,我想知道在所有點(x, y)是在矩形平面has

我可以用這種方式使用List Comprehensions來計算:

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 = ?

謝謝

不幸的是,因為[(a,a)][(a,a,a)]等具有不同的類型,所以不能編寫一個函數來表示它們。

無論如何,一般來說你可以使用

Prelude> let x = [0..2]
Prelude> import Control.Applicative 
Prelude Control.Applicative> (,,) <$> 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]]

或者(感謝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]]

可以使用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)]

你可以使用這樣的東西:

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]]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM