【问题标题】:Alternative ways of defining zipWith using list comprehension without helper functions or extensions使用列表理解定义 zipWith 的替代方法,无需辅助函数或扩展
【发布时间】:2023-03-05 21:48:01
【问题描述】:

我知道您可以将zipWithzip 定义为:

zipwith' f xs ys = [f x y | (x,y) <- zip xs ys]

但是没有zip 怎么办?我在某处读到,您可以像这样使用并行列表理解来做到这一点:

zipwith' f xs ys = [f x y | x <- xs | y <- ys]

但您必须在代码顶部添加 {-# LANGUAGE ParallelListComp #-} 才能使其正常工作,因为它是一个扩展。

是否有任何其他方法可以使用列表理解来定义zipWith,最好不使用辅助函数或扩展?

【问题讨论】:

  • 我认为不理解 O(n^2) 是不可能的。
  • AFAIK,没有。默认情况下,列表解析使用列表的 monad 实例,特别是 >>= 函数,它是使用 concatMap 实现的。 ParallelListComp extension instead desugars[f x y | x <- xs | y <- ys][f x y | (x, y) <- zip xs ys],并使用更高级别的zips 以获得更多表达式。
  • @KennyTM 你会如何在 O(n^2) 中做到这一点?
  • [f x y | (x, i) <- zip xs [0..], (y, j) <- zip ys [0..], i == j] 应该作为 O(n^2) 算法工作,但它仍然依赖于 zip 来实现。您可以编写像g [f x y | x <- xs, y <- ys] 这样的解决方案,其中g 删除您不关心的元素,这也是一个明显较慢的算法,但g 必须使用lengthtake 和@ 987654342@,因此这不适用于无限列表(上面的索引解决方案也不会)。
  • @user2108462:使用(!!)length。好吧,这可能算作辅助功能...

标签: list haskell list-comprehension


【解决方案1】:

没有zip,你必须使用一些——可以说是基本的——列表访问函数,即droptakeWhile。两者都是内置的,因此不是您想要避免的“辅助函数”:

zipW :: (a -> b -> c) -> [a] -> [b] -> [c]
zipW f xs ys = [z | [z] <- takeWhile (not.null)                   
                             [z | [z] <- takeWhile (not.null)     -- ~ map (head.head)
    [ [ [c | (c:_) <- [drop i r]]                                 -- ~ take 1 . drop i
        | (r:_) <- [drop i rs]]                                   -- ~ take 1 . drop i
      | let rs = [[f x y | y<- ys] | x<- xs], i <- [0..]]]]

这将从笛卡尔积中恢复对角线,注意处理无限列表(因此,测量它们的 length 是不可能的)以及有限列表(因此,!! 不能使用)。

~> zipW (,) [1..4] [10..]
[(1,10),(2,11),(3,12),(4,13)]

~> zipW (,) [1..] [10..13]
[(1,10),(2,11),(3,12),(4,13)]

当然它是二次的,只要drop nO(n),它通常是。

如果保证列表是无限的,它会简化很多

zipWi f xs ys = [ rs !! i !! i | let rs = [[f x y | y<- ys] | x<- xs], i <- [0..]]

因为现在可以使用!! 进行列表访问(当然仍然是二次方):

~> 取 4 $ zipWi(,) [0..] [10..]
[(0,10),(1,11),(2,12),(3,13)]

为了使其线性化,我认为递归解决方案可以用unfoldriterate 等编码,但不能用列表推导式编码。

【讨论】:

    猜你喜欢
    • 2017-07-02
    • 1970-01-01
    • 1970-01-01
    • 2019-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多