首页 > 解决方案 > 我可以使用什么函数对其他函数进行多次嵌套调用?

问题描述

我需要以perms这种嵌套方式调用此函数:

e = [1,3,7,10, 25,50]
f = perms (perms (perms (perms (perms (perms [[]] e) e) e) e) e) e
g = [[]] ++ f -- final set of permutations 

perms :: (Eq a, Ord a) => [[a]] -> [a] -> [[a]] 
-- set [a] is a set of existing permutations and set [b] are the elements to add to [a] in all possible permutations
perms xss      [] = xss  -- no unique elements to create new permutations from
perms [xs]     ys = [xs ++ [y] | y <- ys \\ xs ]                         -- last list of xs in list xss 
perms (xs:xss) ys = [xs] ++ [ xs ++ [y] | y <- ys\\xs ] ++ perms xss ys 

简而言之,我想知道是否有一个函数,比如一个花哨的使用,map with (.)或者something它可以以比以下更简洁的语法为我执行其中六个嵌套调用:

f = perms (perms (perms (perms (perms (perms [[]] e) e) e) e) e) e

我相信我可以Int在函数中添加另一个参数,perms以便通过 P(n, r) for r <- [1..6] 进行计数,但这对我来说并不感兴趣。我想知道如何在没有文字嵌套的情况下递归调用自身的同一个函数的 6 个嵌套?

但也许它归结为我的函数中递归设计的错误选择,并且需要废弃整个方法以获得更好的东西?


背景:

这是我试图解决 Graham Hutton Haskell 简介讲座中提出的倒计时游戏解决方案查找器的一部分。(我敢肯定他的解决方案更优雅)

使用 Data.List 库permutations函数不起作用,因为除了 (n=720) 6 元素排列之外,我还需要 (720) 5 元素排列、(360) 4 元素排列、(120 ) 3 元素排列 ...,(6) 1 元素排列和空集解。因为在这个游戏中,您可以随意使用随机选择的 6 个数字中的任意数量或数量。

我查看了 hackage.org 上的源代码permutations,这有点超出我的理解。所以我想我最好自己试试这个。

这是 Hutton 的解决方案,用于查找我刚刚选择查看的数字排列选择。

-- Combinatorial functions

subs :: [a] -> [[a]]
subs []     = [[]]
subs (x:xs) = yss ++ map (x:) yss
              where yss = subs xs

interleave :: a -> [a] -> [[a]]
interleave x []     = [[x]]
interleave x (y:ys) = (x:y:ys) : map (y:) (interleave x ys)

perms :: [a] -> [[a]]
perms []     = [[]]
perms (x:xs) = concat (map (interleave x) (perms xs))

choices :: [a] -> [[a]]
choices = concat . map perms . subs

标签: haskellrecursionpermutationinterleave

解决方案


我会使用iterate,如

iterate (flip perms e) [[]] !! 6

推荐阅读