Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
函数根据条件对列表进行分区-Haskell_Haskell - Fatal编程技术网

函数根据条件对列表进行分区-Haskell

函数根据条件对列表进行分区-Haskell,haskell,Haskell,我正在学习Haskell,我正在做的一个练习是创建一个函数,根据函数的返回值将一个列表划分为三个列表,这样第一个子列表的函数值等于1,第二个子列表的函数值为2,第三个子列表的其他内容都包含在内 函数声明将被读取 partition3 :: (a -> Int) -> [a] -> ([a], [a], [a]) partition3 _ [] = [] 作为一个初级示例,请考虑 partition3 (\x -> mod x 5) [1..10] = ([1,6], [

我正在学习Haskell,我正在做的一个练习是创建一个函数,根据函数的返回值将一个列表划分为三个列表,这样第一个子列表的函数值等于1,第二个子列表的函数值为2,第三个子列表的其他内容都包含在内

函数声明将被读取

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语法。所以我最好不要使用已经实现的函数。答案很好!谢谢你的解释