我可以以一种简洁的方式计算立方体列表吗?

发布于 2024-10-10 08:26:32 字数 271 浏览 4 评论 0原文

可以用高阶函数、Monad 或其他什么来简化以下函数吗?

cube list = [(x, y, z) | x <- list, y <- list, z <- list]

该函数只是创建列表元素的所有三重排列的列表。例如:

> cube [1..2]
[(1,1,1),(1,1,2),(1,2,1),(1,2,2),(2,1,1),(2,1,2),(2,2,1),(2,2,2)]

Can the following function be simplified with higher order functions, Monads or what have you?

cube list = [(x, y, z) | x <- list, y <- list, z <- list]

The function simply creates a list of all triple-permutations of the elements of the list. For example:

> cube [1..2]
[(1,1,1),(1,1,2),(1,2,1),(1,2,2),(2,1,1),(2,1,2),(2,2,1),(2,2,2)]

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

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

发布评论

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

评论(6

萌面超妹 2024-10-17 08:26:32

从比尔的回答来看,因为这是使用列表单子的代码,所以我们可以使用“应用程序”风格来“使用高阶函数”。这是否是一个好主意留给工程师作为练习。

import Control.Applicative

cube :: [a] -> [b] -> [c] -> [(a,b,c)]
cube x y z = (,,) <
gt; x <*> y <*> z

Going from Bill's answer, because this is code uses the list monad, we can use "applicative" style to do "with higher-order functions". Whether or not this is a good idea is left as an exercise for the engineer.

import Control.Applicative

cube :: [a] -> [b] -> [c] -> [(a,b,c)]
cube x y z = (,,) <
gt; x <*> y <*> z
草莓酥 2024-10-17 08:26:32

尽管它为您提供列表而不是元组,但您可以使用 Control.Monad

> let list = [1..2]
> sequence [list, list, list]
[[1,1,1],[1,1,2],[1,2,1],[1,2,2],[2,1,1],[2,1,2],[2,2,1],[2,2,2]]

sequence 函数很简洁,因为尽管它的“预期”目的是获取操作列表,按顺序执行它们,并在列表中返回其结果,在列表中使用它 monad 可以免费为您提供组合。

> sequence $ replicate 3 "01"
["000","001","010","011","100","101","110","111"]

Although it gives you lists instead of tuples, you can use the sequence function in Control.Monad:

> let list = [1..2]
> sequence [list, list, list]
[[1,1,1],[1,1,2],[1,2,1],[1,2,2],[2,1,1],[2,1,2],[2,2,1],[2,2,2]]

The sequence function is neat because, although its "intended" purpose is to take a list of actions, do them in order, and return their results in a list, using it on the list monad gives you combinations for free.

> sequence $ replicate 3 "01"
["000","001","010","011","100","101","110","111"]
阪姬 2024-10-17 08:26:32

事实上,您的列表理解是 List monad 的一种用法。

另一种写法是:

cube :: [a] -> [(a,a,a)]
cube list = do
  x <- list
  y <- list
  z <- list
  return (x, y, z)

In fact, your list comprehension is a usage of the List monad.

Another way to write this is:

cube :: [a] -> [(a,a,a)]
cube list = do
  x <- list
  y <- list
  z <- list
  return (x, y, z)
初见你 2024-10-17 08:26:32

这并不是一个严肃的答案,但无论如何我必须建议它。主要是为了疯狂。

import Control.Monad
import Control.Monad.Instances

cube :: [a] -> [(a, a, a)]
cube = join . join $ liftM3 (,,)

和那个人玩得开心吧。 :)

This isn't really a serious answer, but I have to suggest it anyway. Mostly for the sake of craziness.

import Control.Monad
import Control.Monad.Instances

cube :: [a] -> [(a, a, a)]
cube = join . join $ liftM3 (,,)

Have fun with that one. :)

苏辞 2024-10-17 08:26:32

为了模仿 Joey Adams 所做的事情:

g>replicateM 3 [1..2]
[[1,1,1],[1,1,2],[1,2,1],[1,2,2],[2,1,1],[2,1,2],[2,2,1],[2,2,2]]

对于完整的解决方案(传递一个列表并获取 3 元组),可以这样做:

g>let cube = map (\(a:b:c:_) -> (a, b, c)) . replicateM 3
cube :: [t] -> [(t, t, t)]
(0.00 secs, 526724 bytes)
g>cube [1..2]
[(1,1,1),(1,1,2),(1,2,1),(1,2,2),(2,1,1),(2,1,2),(2,2,1),(2,2,2)]
it :: [(Integer, Integer, Integer)]

但是恕我直言,Edward Z. Yang 的解决方案占据主导地位。

To model after what Joey Adams did:

g>replicateM 3 [1..2]
[[1,1,1],[1,1,2],[1,2,1],[1,2,2],[2,1,1],[2,1,2],[2,2,1],[2,2,2]]

For the full solution(pass it a list and get 3-tuples), something like this can be done:

g>let cube = map (\(a:b:c:_) -> (a, b, c)) . replicateM 3
cube :: [t] -> [(t, t, t)]
(0.00 secs, 526724 bytes)
g>cube [1..2]
[(1,1,1),(1,1,2),(1,2,1),(1,2,2),(2,1,1),(2,1,2),(2,2,1),(2,2,2)]
it :: [(Integer, Integer, Integer)]

But IMHO, Edward Z. Yang's solution reigns supreme.

时光病人 2024-10-17 08:26:32

如果你可以拥有位,谁还需要单子?

import Data.Bits

cube :: [(Int,Int,Int)]
cube = map tuple [0..7] where
   tuple x = (1 + div (x .&. 4)  4, 1 + div (x .&. 2)  2, 1 + x .&. 1)

Who needs monads if you can have bits?

import Data.Bits

cube :: [(Int,Int,Int)]
cube = map tuple [0..7] where
   tuple x = (1 + div (x .&. 4)  4, 1 + div (x .&. 2)  2, 1 + x .&. 1)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文