可变长度与固定集合的组合
Combinations of variable length with fixed set
我有一组可能的颜色定义如下:
data Peg = Red | Green | Blue | Yellow | Orange | Purple
deriving (Show, Eq, Ord)
colors = [Red, Green, Blue, Yellow, Orange, Purple]
代码是这样定义的颜色组合:
type Code = [Peg]
我希望能够生成所有可能的长度组合列表 len
,这些组合可以由定义的颜色组成。
这是我的原创。我还在学习,所以我什至不确定我是否犯了一些不受支持的语法错误或结构。
allCodes :: Int -> [Code]
allCodes len = map (\p -> Code p) (permutations len)
where
permutations::Int->[Peg]
permutations 0 = [[]]
permutations n = [x:xs | x <- colors, xs <- permutations (n - 1)]
编译失败,出现错误:
[1 of 1] Compiling HW02 ( HW02.hs, interpreted )
HW02.hs:59:27: Not in scope: data constructor `Code'
Failed, modules loaded: none.
Code
在我使用过它的其他地方也可以使用,所以我不确定这里发生了什么。我知道像 replicateM
这样的函数可以很容易地解决这个问题,但我只想使用 Prelude
.
中的函数
bhelkir 对问题的评论已正确诊断出您的错误,因此我将跳过它。
您的 allCodes
函数的逻辑基本上是合理的(撇开排列与组合问题)。值得指出的一件事是,通过在 Prelude
:
中使用两个函数,可以实现与单行代码相同的效果
allCodes :: Int -> [Code]
allCodes len = sequence (replicate len colors)
跟随它一直到堆栈底部是有益的。首先,replicate
函数做一个指定长度的列表,用相同的值填充所有位置:
replicate :: Int -> a -> [a]
replicate 0 _ = []
replicate n a | n > 0 = a : replicate (n-1) a
| otherwise = error "replicate called with n < 0"
所以replicate 3 colors
产生一个包含三个元素的列表,都是colors
列表
现在,sequence
函数有点神奇:
sequence :: Monad m => [m a] -> m [a]
sequence [] = return []
sequence (ma:mas) =
do a <- ma
as <- sequence mas
return (a:as)
然而,当m = []
时,这等同于:
sequence' :: [[a]] -> [[a]]
sequence' [] = [[]]
sequence' (ma:mas) = [(a:as) | a <- ma, as <- sequence mas]
所以基本上,单行代码与您的解决方案的想法相同,但重构为两个可重复使用的部分。
我有一组可能的颜色定义如下:
data Peg = Red | Green | Blue | Yellow | Orange | Purple
deriving (Show, Eq, Ord)
colors = [Red, Green, Blue, Yellow, Orange, Purple]
代码是这样定义的颜色组合:
type Code = [Peg]
我希望能够生成所有可能的长度组合列表 len
,这些组合可以由定义的颜色组成。
这是我的原创。我还在学习,所以我什至不确定我是否犯了一些不受支持的语法错误或结构。
allCodes :: Int -> [Code]
allCodes len = map (\p -> Code p) (permutations len)
where
permutations::Int->[Peg]
permutations 0 = [[]]
permutations n = [x:xs | x <- colors, xs <- permutations (n - 1)]
编译失败,出现错误:
[1 of 1] Compiling HW02 ( HW02.hs, interpreted )
HW02.hs:59:27: Not in scope: data constructor `Code'
Failed, modules loaded: none.
Code
在我使用过它的其他地方也可以使用,所以我不确定这里发生了什么。我知道像 replicateM
这样的函数可以很容易地解决这个问题,但我只想使用 Prelude
.
bhelkir 对问题的评论已正确诊断出您的错误,因此我将跳过它。
您的 allCodes
函数的逻辑基本上是合理的(撇开排列与组合问题)。值得指出的一件事是,通过在 Prelude
:
allCodes :: Int -> [Code]
allCodes len = sequence (replicate len colors)
跟随它一直到堆栈底部是有益的。首先,replicate
函数做一个指定长度的列表,用相同的值填充所有位置:
replicate :: Int -> a -> [a]
replicate 0 _ = []
replicate n a | n > 0 = a : replicate (n-1) a
| otherwise = error "replicate called with n < 0"
所以replicate 3 colors
产生一个包含三个元素的列表,都是colors
列表
现在,sequence
函数有点神奇:
sequence :: Monad m => [m a] -> m [a]
sequence [] = return []
sequence (ma:mas) =
do a <- ma
as <- sequence mas
return (a:as)
然而,当m = []
时,这等同于:
sequence' :: [[a]] -> [[a]]
sequence' [] = [[]]
sequence' (ma:mas) = [(a:as) | a <- ma, as <- sequence mas]
所以基本上,单行代码与您的解决方案的想法相同,但重构为两个可重复使用的部分。