Haskell有一个贪婪的zip(一个保留所有元素)? [英] Does Haskell have a greedy zip (one preserving all elements)?

查看:134
本文介绍了Haskell有一个贪婪的zip(一个保留所有元素)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不确定这里的命名是否正确,但我想知道是否在Haskell中有一个贪婪的zip函数。这意味着如果我有

  a = [1,2,3] 
b = [4,5]
zip'ab
#=> [(Just 1,Just 4),(Just 2,Just 5),(Just 3,Nothing)]

其中 zip'是贪婪的zip函数,它将返回长列表长度的元组列表,以及长列表包含元素的列表,但是较短的列表不会有 Nothing 放入相应的元组位置。我不是问如何写这个,而是想知道这是否作为内置存在。



这是我的实现(这可能不是很好) p>

  zip':: [a]  - > [b]  - > [(也许a,也许b)] 
zip'(a:xs)[] =(只是一个,没有):zip'xs []
zip'[](b:ys)=(没有,只是b):zip'[] ys
zip'[] _ = []
zip'(a:xs)(b:ys)=(只是a,只是b):zip' XS YS


解决方案

一个贪婪拉链可以整齐地通过一个表达非独占析取类型(相对于或者,这是一个独占析取)。两个流行的软件包提供。一种是极简主义,无依赖关系的 数据或

  GHCi>导入Data.Or 
GHCi> :t zipOr
zipOr :: [a] - > [b] - > [或者b]
GHCi> zipOr [1,2,3] [4,5]
[Both 1 4,Both 2 5,Fst 3]

另一个是

这些
带有许多花里胡哨的口哨声:

  GHCi>导入数据。这些
GHCi> import Data.Align
GHCi> :t align
align :: Align f => f a - > f b - > f(这些a b)
GHCi> align [1,2,3] [4,5]
[This 1 4,This 2 5,This 3]

我相信或者ab 这些ab 表示您的意图优于<$ c $ (后一种类型包括(Nothing,Nothing),这是贪婪的zip永远不会产生的)。不过,您可以使用 Data.Or zipOrWith 来表达 zip' c code



$ b zip':: [a] - > [b] - > [(也许a,也许b)]
zip'= zipOrWith $ \xy - >案例xy是
这两个x y - > (Just x,Just y)
Fst x - > (Just x,Nothing)
Snd y - > (Nothing,Just y)

...或 alignWith Data.Align :

  import Data.These 
import Data.Align

zip':: Align f => f a - > f b - > f(也许a,也许b)
zip'= alignWith $ \xy - >案例xy是
这些x y - > (Just x,Just y)
这个x - > (Just x,Nothing)
那y - > (Nothing,Just y)

Data.Align ,实际上是以 padZip


I'm not exactly sure if my nomenclature is correct here, but I was wondering if there was a zip function in Haskell that was greedy. This means that if I had

a = [1, 2, 3]
b = [4, 5]
zip' a b
#=> [(Just 1, Just 4),(Just 2, Just 5),(Just 3, Nothing)]

...where zip' is the greedy zip function, it would return a list of tuples the length of the longer list, and where the longer list has an element, but the shorter list does not Nothing is put in the respective tuple position. I am not asking how to write this, but instead was wondering if this exists as a built-in.

Here is my implementation (which is probably not great)

zip' :: [a] -> [b] -> [(Maybe a, Maybe b)]
zip' (a:xs) [] = (Just a, Nothing) : zip' xs []
zip' [] (b:ys) = (Nothing, Just b) : zip' [] ys
zip' [] _ = []
zip' (a:xs) (b:ys) = (Just a, Just b) : zip' xs ys

解决方案

A greedy zip can be neatly expressed through a non-exclusive disjunction type (as opposed to Either, which is an exclusive disjunction). Two popular packages offer that. One is the minimalist, dependency-free data-or:

GHCi> import Data.Or
GHCi> :t zipOr
zipOr :: [a] -> [b] -> [Or a b]
GHCi> zipOr [1, 2, 3] [4, 5]
[Both 1 4,Both 2 5,Fst 3]

The other is these, which comes with lots of bells and whistles:

GHCi> import Data.These 
GHCi> import Data.Align
GHCi> :t align
align :: Align f => f a -> f b -> f (These a b)
GHCi> align [1, 2, 3] [4, 5]
[These 1 4,These 2 5,This 3]

I believe Or a b and These a b express your intent better than (Maybe a, Maybe b) (the latter type includes (Nothing, Nothing), which a greedy zip will never produce). Still, you can express your zip' using either zipOrWith from Data.Or...

import Data.Or

zip' :: [a] -> [b] -> [(Maybe a, Maybe b)]
zip' = zipOrWith $ \xy -> case xy of
    Both x y -> (Just x, Just y)
    Fst x -> (Just x, Nothing)
    Snd y -> (Nothing, Just y)

... or alignWith from Data.Align:

import Data.These
import Data.Align

zip' :: Align f => f a -> f b -> f (Maybe a, Maybe b)
zip' = alignWith $ \xy -> case xy of
    These x y -> (Just x, Just y)
    This x -> (Just x, Nothing)
    That y -> (Nothing, Just y)

Data.Align, in fact, provides your function under the name of padZip.

这篇关于Haskell有一个贪婪的zip(一个保留所有元素)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆