我不确定我的命名法是否正确,但我想知道Haskell中是否有一个贪婪的zip函数.这意味着,如果我有
a = [1, 2, 3]
b = [4, 5]
zip' a b
#=> [(Just 1, Just 4),(Just 2, Just 5),(Just 3, Nothing)]
Run Code Online (Sandbox Code Playgroud)
... zip'
贪婪的zip函数在哪里,它将返回一个元组列表,列表的长度更长,列表中有一个元素,但较短的列表不会Nothing
放在相应的元组位置.我不是问如何写这个,而是想知道这是否作为内置存在.
这是我的实现(可能不是很好)
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
Run Code Online (Sandbox Code Playgroud)
dup*_*ode 37
贪婪的拉链可以通过非排他性的分离类型(相反Either
,这是一种独特的分离)整齐地表达出来.两个受欢迎的套餐提供.一个是极简主义,无依赖性的数据 - 或:
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]
Run Code Online (Sandbox Code Playgroud)
另一个是这些,它带有许多花里胡哨的东西:
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]
Run Code Online (Sandbox Code Playgroud)
我相信Or a b
并These a b
表达你的意图比(Maybe a, Maybe b)
(后一种类型包括(Nothing, Nothing)
,贪婪的拉链永远不会产生).不过,你可以表达你的zip'
使用无论是zipOrWith
从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)
Run Code Online (Sandbox Code Playgroud)
......或alignWith
来自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)
Run Code Online (Sandbox Code Playgroud)
Data.Align
实际上,它提供了你的名字下的功能padZip
.
归档时间: |
|
查看次数: |
807 次 |
最近记录: |