【问题标题】:filtered list cartesian product without intermediate list没有中间列表的过滤列表笛卡尔积
【发布时间】:2017-01-29 16:07:35
【问题描述】:

我正在尝试从给定的列表列表中创建过滤的笛卡尔积。天真的解决方案如下:

import Data.Traversable (sequence)

predicate :: [T] -> Bool
predicate = ...

filteredCartesianProduct :: [[T]] -> [[T]]
filteredCartesianProduct = filter predicate . sequence

traversable 是否足够强大,可以在不创建中间列表的情况下完成它?有没有惯用的方法来做到这一点?

【问题讨论】:

  • 假设您的predicate 函数的签名是正确的,那么您对filteredPowerSet 的实现是不正确的。你为什么要用sequence 组成filter predicate?这不进行类型检查。你的实现不应该是filteredPowerSet = filter predicate吗?
  • 声明的类型意味着您已经收到(或至少期待)一个幂集,而不是一个集,作为参数。
  • sequence 不会创建 powerset。一方面,如果长度相等,它会生成一个列表列表。
  • sequence 计算笛卡尔积 -- 也许这就是你的意思?
  • filtered_sequence _ [] = [[]]; filtered_sequence (x:xs) = [z|u<-x, us<-sequence xs, let z = u:us, f z]。注意f 不会传播,也就是说,要使这个定义递归,可以在理解内写filtered_sequence (const True) xs

标签: haskell traversable


【解决方案1】:

traverse 在这里对predicate 具有all foo 形式的模式进行编码,对于某些foo。那么filteredCartesianProduct就是traverse (filter foo)

如果predicate 对它说是的任何列表的每个前缀都说是,那么你就有了回溯模式:

filteredCartesianProduct = foldlM (\accum factor -> [new | x <- factor, let new = accum ++ [x], predicate new]) []

我想知道如何摆脱++ [_] 的气味。

【讨论】:

    猜你喜欢
    • 2012-03-24
    • 2020-12-21
    • 2015-12-05
    • 1970-01-01
    • 2017-07-15
    • 2012-01-03
    • 2021-10-22
    • 2011-07-10
    • 1970-01-01
    相关资源
    最近更新 更多