我想编写一个函数,该函数需要一个列表并根据函数的输出构建一定长度的列表的子集。Haskell:将函数输出添加到列表直到某个长度
如果我是在排序列表XS的第50个元素只是感兴趣,然后我会用fst (splitAt 50 (sort xs)).
然而,问题是,在我的列表中的元素依赖于在同一列表中的其他元素。如果我选择元素p,那么我也必须选择元素q和r,即使它们不在我列表的前50个元素中。我使用了一个函数finderFunc,它从列表xs中获取一个元素a,并返回一个列表,其中包含元素a及其所有必需的元素。 finderFunc工作正常。现在,面临的挑战是编写一个函数,根据finderFunc的多个输出生成一个总长度为50的列表。
这是我在这样的尝试:
finish :: [a] -> [a] -> [a]
--This is the base case, which adds nothing to the final list
finish [] fs = []
--The function is recursive, so the fs variable is necessary so that finish
-- can forward the incomplete list to itself.
finish ps fs
-- If the final list fs is too small, add elements to it
| length fs < 50 && length (fs ++ newrs) <= 50 = fs ++ finish newps newrs
-- If the length is met, then add nothing to the list and quit
| length fs >= 50 = finish [] fs
-- These guard statements are currently lacking, not the main problem
| otherwise = finish [] fs
where
--Sort the candidate list
sortedps = sort ps
--(finderFunc a) returns a list of type [a] containing a and all the
-- elements which are required to go with it. This is the interesting
-- bit. rs is also a subset of the candidate list ps.
rs = finderFunc (head sortedps)
--Remove those elements which are already in the final list, because
-- there can be overlap
newrs = filter (`notElem` fs) rs
--Remove the elements we will add to the list from the new list
-- of candidates
newps = filter (`notElem` rs) ps
我认识到,上面的if语句,在某些情况下,没有给我确切地50个元素的列表。这不是主要问题,现在。问题是我的功能完成并不像我预期的那样工作。它不仅会在输出列表中生成重复的元素,而且有时会远远高于列表中要包含的元素的总数。
写这个的方式,我通常会用一个空的列表来调用它,例如:finish xs []
,这样它建立的列表就以一个空列表开始。
通过其他一些小的修改,这确实是解决方案!不过,我花了一段时间才看到它。谢谢! –