2015-09-20 23 views
0

我有一个Haskell中的字符串列表,我需要在另一个列表中获取奇数长度的元素。如何使用foldr,foldl,foldr1,foldl1,过滤器,地图等高阶函数来完成这项工作?我将非常感谢你的帮助。在这种情况下可以使用列表理解吗?在Haskell字符串列表中获取奇数长度的元素

回答

5

看来你知道filter存在(因为你已经提到过),但可能不确定它是如何工作的。如果你想提取列表的特定子集,这似乎是正确的路径。如果你看一下它的类型签名,你会发现它非常直截了当:

(a -> Bool) -> [a] -> [a] 

也就是说,它需要返回true或false(即真正在新的一组包含一个函数,否则为false )并产生一个新的列表。同样,Haskell在Prelude中提供了一个名为odd的函数。它的签名如下所示:

Integral a => a -> Bool 

也就是说,它可以采取任何Integral类型,如果是奇数,否则为false返回True。

现在,让我们考虑一个解决方案:

filter odd [1..10] 

这将提取[1,10]之间的所有奇数。

我注意到你提到了列表解析。如果您已经提供了一个列表,并且您只是简单地对其进行过滤,那么您可能不想使用它。然而,列表理解将是完全可接受的解决方案:

[x | x <- [1..10], odd x] 

通常,列表解析被用于表达列表的产生更复杂的约束条件。

现在,实际回答你的问题。因为我们知道,我们可以过滤数字,如果我们使用Hoogle搜索以下类型(注意String简直是[Char]):

[a] -> Int 

你会看到一个length功能。用一些函数组合,我们可以很快看到如何创建一个过滤奇数长度的函数。总之,我们有odd这是Int -> Bool(在这种情况下),我们有length这是[a] -> Int或 - 特别是 - String -> Int。我们的解决方案现在看起来像这样:

filter (odd . length) ["abc","def","eh","123","hm","even"] 
1

在这里你去。

getOddOnes = filter . flip (foldr (const (. not)) id) $ False 

注意:如果你把这个作为你的功课,你最好准备好解释它!

+0

虽然可爱,你的'isOddLength'部分是不必要的复杂。沿着同样的路线,更加直截了当的解决方案是'getOddOnes = filter $ foldr(const not)False' – Cactus

+0

@Cactus,我认为有理由更喜欢左折叠,而这个答案是为了匹配在某种意义上的问题。 – dfeuer