Haskell:避免使用if进行排列?

Haskell:避免使用if进行排列?,haskell,Haskell,我试图用“一行程序”在Haskell中生成列表的排列。这就是我到目前为止所做的: perms xs=如果长度xs==0,则[[]]else[x:ys | x您需要的更高的函数与您的if表达式执行相同的操作:检查给定的谓词,如果为真,则计算为表达式1,否则计算为表达式2 我在标准库中没有找到此函数,但这是您正在寻找的函数: myBranchFunction :: t -> t -> [a] -> t myBranchFunction e1 e2 xs = if length xs

我试图用“一行程序”在Haskell中生成列表的排列。这就是我到目前为止所做的:


perms xs=如果长度xs==0,则[[]]else[x:ys | x您需要的更高的函数与您的
if
表达式执行相同的操作:检查给定的谓词,如果为真,则计算为表达式1,否则计算为表达式2

我在标准库中没有找到此函数,但这是您正在寻找的函数:

myBranchFunction :: t -> t -> [a] -> t
myBranchFunction e1 e2 xs = if length xs == 0 then e1 else e2
perms xs = filter (\l -> length l == length xs) $ foldr step [[]] xs
    where step x acc = (map (x:) . perms $ delete x xs) ++ acc
(如果愿意,您可以将
length
作为
myBranchFunction
的参数,从而进一步推广此功能。)

然后您可以这样定义
perms'

perms' :: Eq a => [a] -> [[a]]
perms' xs = myBranchFunction [[]] [x:ys | x <- xs, ys <- perms $ delete x xs] xs
perms'::Eq a=>[a]->[a]]

perms的xs=myBranchFunction[][x:ys | x我通过使用
foldr
实现了这个
perms
,但是它变得更复杂了。很难相信这就是你想要的:

myBranchFunction :: t -> t -> [a] -> t
myBranchFunction e1 e2 xs = if length xs == 0 then e1 else e2
perms xs = filter (\l -> length l == length xs) $ foldr step [[]] xs
    where step x acc = (map (x:) . perms $ delete x xs) ++ acc

如果您觉得只需去掉
If
而不对函数进行任何有趣的更改就可以了,
base-4.7.0.0
(与GHC 7.8捆绑在一起)包含在
Data.Bool

perms xs = bool [[]] [x:ys | x <- xs, ys <- perms $ delete x xs] $ not (null xs)

perms xs=bool[[][x:ys|x
[ghci]让perms1 xs=[x:ys|x]来回答这个问题。实际的策略是模式匹配。我建议您阅读整本书,它是免费的,在线的。这个函数有多个分支的事实足以避免一行代码(这个函数在我看来读起来不太好)我不想要我说过的多部分或模式匹配定义。我对Haskell很熟悉,不必使用那本书。使用模式匹配或if表达式有什么问题?@mtahmed我不确定这一点,但我认为你不能使用fold将递归封装在
perms
函数后面(如果这正是您想要做的。)原因是
perms
需要对列表中的每个值在整个列表上递归,而不是一次一个地从列表中获取一个值和一个累加器。我当然可能是错的…这可能是一个更强大的递归方案。列表上的折叠是一种变形,但这个问题更复杂ke通过树而不是列表递归(底层数据结构恰好是一个列表).在树结构上正确操作的递归方案可能能够在一行程序中实现这一点,但我不知道有哪个库提供足够的函数并实现这样的函数远不是一行程序。因为列表理解只是一元计算的语法糖,所以您要找的是
delete
语句前面的
guard
。您也可以将它放在
x前面,不幸的是,这对于OP来说还不够。在他的实现中,
perms[]=[[[]
。对于早期版本的base,
可能
listToMaybe
可能会被滥用,产生类似的效果:
可能[[]](const[x:ys | x我所寻找的基本上是一种以某种方式“折叠”这个类似于树的递归的方法…似乎不存在这样的构造…所以也许我会尝试写一个用于“教育目的”…是时候分类理论了!:p