函数根据条件对列表进行分区-Haskell
我正在学习Haskell,我正在做的一个练习是创建一个函数,根据函数的返回值将一个列表划分为三个列表,这样第一个子列表的函数值等于1,第二个子列表的函数值为2,第三个子列表的其他内容都包含在内 函数声明将被读取函数根据条件对列表进行分区-Haskell,haskell,Haskell,我正在学习Haskell,我正在做的一个练习是创建一个函数,根据函数的返回值将一个列表划分为三个列表,这样第一个子列表的函数值等于1,第二个子列表的函数值为2,第三个子列表的其他内容都包含在内 函数声明将被读取 partition3 :: (a -> Int) -> [a] -> ([a], [a], [a]) partition3 _ [] = [] 作为一个初级示例,请考虑 partition3 (\x -> mod x 5) [1..10] = ([1,6], [
partition3 :: (a -> Int) -> [a] -> ([a], [a], [a])
partition3 _ [] = []
作为一个初级示例,请考虑
partition3 (\x -> mod x 5) [1..10] = ([1,6], [2,7], [3,4,5,8,9,10])
现在,我已经编写了函数filterAny
,isSuitable
,removeIf
,不适用。完整代码如下:
filterAny :: [a -> Bool] -> [a] -> [a]
filterAny _ [] = []
filterAny ps (x:xs)
| isSuitable ps x = x : filterAny ps xs
| otherwise = filterAny ps xs
isSuitable :: [a -> Bool] -> a -> Bool
isSuitable [] _ = False
isSuitable (p:ps) v
| p v = True
| otherwise = isSuitable ps v
removeIf :: [a -> Bool] -> [a] -> [a]
removeIf _ [] = []
removeIf ps (x:xs)
| isNotSuitable ps x = x : removeIf ps xs
| otherwise = removeIf ps xs
isNotSuitable :: [a -> Bool] -> a -> Bool
isNotSuitable [] _ = True
isNotSuitable (p:ps) v
| p v = False
| otherwise = isNotSuitable ps v
使用这些函数,我们可以获得分区3所需的输出:
filterAny [(\x -> mod x 5 == 1)] [1..10] = [1,6]
filterAny [(\x -> mod x 5 == 2)] [1..10] = [2,7]
removeIf [even, (\x -> x > 5)] [1..10] = [3,4,5,8,9,10]
不幸的是,我还没有弄明白如何编写这个函数来输出([1,6],[2,7],[3,4,5,8,9,10])
一种高级的方法来考虑“创建”一个类似(a,b,c)
类型的值,就是考虑如何像构造函数一样“构造”它。在这种情况下,(a,b,c)
有一个构造函数,(u,u,u)
。所以你需要考虑一下要放在第一个插槽里的东西,要放在第二个插槽里的东西,还有要放在第三个插槽里的东西。。。你完成了
让我们这样概括一下我们的功能:
partition3 :: (a -> Int) -> [a] -> ([a], [a], [a])
partition3 f xs = (_, _, _)
我们知道我们的最终答案是(u,u,u)
,其中“空格”包含我们要放入元组的每个项。让我们给每一个空格起一个有用的名字
partition3 :: (a -> Int) -> [a] -> ([a], [a], [a])
partition3 f xs = (equalsOne, equalsTwo, theRest)
where
equalsOne = ???
equalsTwo = ???
theRest = ???
现在,您只需要将equalsOne
作为xs
中与所需属性相匹配的项,等等。equalsOne
的属性是“当您对其应用f
时,如果它给出1
,则值x
匹配”。因此,让我们使用filterAny
:
partition3 :: (a -> Int) -> [a] -> ([a], [a], [a])
partition3 f xs = (equalsOne, equalsTwo, theRest)
where
equalsOne = filterAny [\x -> f x == 1] xs
equalsTwo = ???
theRest = ???
这里我们过滤xs
中的任何项目,如果对其应用f
,则会给出1
你能想出方法来实现等式two
和rest
,方法相同吗?FWIW,数据。List
包含分区
,它将为你提供([a],[a])
。你不能用它两次来生成一个([a],([a],[a])
?我不确定你是否需要使用这些函数。您可以在这里使用显式递归。@MarkSeemann我正在练习学习Haskell语法。所以我最好不要使用已经实现的函数。答案很好!谢谢你的解释