【问题标题】:Find any possible bondings of a list and predicate查找列表和谓词的任何可能结合
【发布时间】:2021-12-25 17:35:17
【问题描述】:

我的任务是我想创建一个函数来查找给定列表和谓词的任何可能的“绑定”,但我找不到正确的解决方案。

二元谓词pls 的绑定是bs :: [ (a,a) ] 对的列表,满足以下条件

  1. ls 中的每个元素在 map fst bs 中仅出现一次,在 map snd bs 中仅出现一次
  2. 如果(x,y) 出现在bs 中,那么xy 都必须出现在ls 中。
  3. 如果(x,y) 出现在bs 中,那么(y,x) 也会出现在bs 中。
  4. 如果bs 中出现一对(x,y),则x 不等于y
  5. 如果(x,y) 出现在bs 中,那么p x y 就是True

此外,我认为对这个问题有用的函数是以下findBonding :: Eq a => (a -> a -> Bool) -> [a] -> Maybe [(a,a)],这样findBonding p lsp 作为谓词,将ls 作为整数列表。

例如,findBonding (\x -> \y -> odd(x+y)) [2,3,4,5,6,7] 应该返回 Just [(2,3),(3,2),(4,5),(5,4),(6,7),(7,6)]

ls(列表)中的foldrp(谓词)声明findBonding 是一个好主意,作为应该声明要查找然后循环的函数的函数在每两个项目上找到正确的对并将它们作为列表返回。

【问题讨论】:

  • 为什么 (2,5)(3,4) 不应该出现在您的示例中的返回列表中?
  • 返回Just []和返回Nothing有什么区别?如果它们的含义相同,或者不可能,那么您的函数的返回值不应包含在 Maybe 中。
  • 它完全可以是一对是的!这个想法是它返回一个可能的对列表。
  • 例如,如果我们传递findBonding (\x -> \y -> even(x+y)) [2,3,4,5,6,7],则函数返回Nothing,因为在这种情况下不存在绑定,因为无论前两对如何创建,您最终都会添加一个奇数和第三对的偶数加起来
  • 答案已更新。看看这是否符合您现在的要求。

标签: list haskell functional-programming predicate


【解决方案1】:

根据您对“绑定”的最终定义,这应该可以满足您的要求:

import Data.Maybe

-- > removeEach [1,2,3,4] == [(1,[2,3,4]),(2,[1,3,4]),(3,[1,2,4]),(4,[1,2,3])]
removeEach :: [a] -> [(a,[a])]
removeEach [] = []
removeEach (x:xs) = (x,xs):map (fmap (x:)) (removeEach xs)

-- > findBonding (\x -> \y -> odd(x+y)) [2,3,4,5,6,7] == Just [(2,3),(3,2),(4,5),(5,4),(6,7),(7,6)]
-- > findBonding (\x -> \y -> even(x+y)) [2,3,4,5,6,7] == Nothing
findBonding :: (a -> a -> Bool) -> [a] -> Maybe [(a,a)]
findBonding f = listToMaybe . go where
  go [] = [[]]
  go (x:xs) = [(x,y):(y,x):xys | (y,ys) <- removeEach xs, f x y && f y x, xys <- go ys]

我创建了辅助函数removeEach,为列表中的每个元素提供该元素以及没有它的列表。

findBonding 函数获取列表 x 的头部,然后在列表中找到一个元素 y 使得 f x yf y x 都成立,产生这些对,然后在余数上递归的名单。它使用外部列表作为非确定性 monad,以确保如果任何可能的配对组合有效,它将找到一个。

【讨论】:

  • 你的最后一句话没有描述你的代码实际上在做什么。 (我无法阅读当前格式错误的问题,所以我看不出它是否符合 OP 的要求。)
  • @WillNess 现在措辞如何?
  • 我的意思是,从表面上看,它没有找到“a”匹配元素,而是所有匹配元素,它在没有元素的情况下不在尾部递归,而是在没有元素的情况下递归整个列表元素。你现在已经把那部分去掉了,所以“剩余”是什么意思现在有点不清楚。
  • @WillNess“它不是在没有元素的情况下在尾部递归,而是在没有元素的整个列表上递归”但是我将参数模式匹配为(x:xs),所以xs已经是尾部,并且然后removeEach xs 的每个结果都会给我一个ys,这是没有匹配元素的结果,也是我递归的结果。
  • 我第一次发表评论时错过了listToMaybe,仅指列表理解部分。 listToMaybe 你写的完全正确。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-01
  • 2020-10-01
  • 1970-01-01
  • 2011-03-12
  • 1970-01-01
相关资源
最近更新 更多