我有以下功能
combinations :: [[a]] -> [[a]]
combinations [] = [[]]
combinations (xs:xss) = concat [map (x:) yss | x <- xs]
where yss = combinations xss
产生其元素之间的所有组合:
*Main> combinations [[1,2],[2,3,4],[5,6]]
[[1,2,5],[1,2,6],[1,3,5],[1,3,6],[1,4,5],[1,4,6],[2,2,5],[2,2,6],[2,3,5],[2,3,6]
,[2,4,5],[2,4,6]]
我觉得必须有一种monadic方式来做到这一点
foobar = do
n <- [1,2]
ch <- [3,4,5]
return[n,ch]
这是我走了多远。但我被卡住了。
答案 0 :(得分:3)
列表monad的功能为sequence
。
> :t sequence
sequence :: Monad m => [m a] -> m [a]
> sequence [[1,2],[2,3,4],[5,6]]
[[1,2,5],[1,2,6],[1,3,5],[1,3,6],[1,4,5],[1,4,6],[2,2,5],[2,2,6],[2,3,5],[2,3,6],
[2,4,5],[2,4,6]]
答案 1 :(得分:1)
我能想出的最好的是
combinations [] = [[]]
combinations (xs:xss) = do
x <- xs
ys <- combinations xss
return $ x : ys
我得出这个的方式是我首先将列表理解转换为monadic代码(这也意味着删除concat
以使其进行类型检查)
combinations (xs:xss) =
let yss = combinations xss
in do
x <- xs
map (x:) yss
然后我意识到map (x:) yss
正是fmap (x:) yss
,这正是yss >>= return . (x:)
,所以我知道我可以做到
combinations (xs:xss) =
let yss = combinations xss
in do
x <- xs
ys <- yss
return $ x : ys
然后它可以内联为
combinations (xs:xss) = do
x <- xs
ys <- combinations xss
return $ x : ys