2016-12-26 20 views
22

İsimlendirmemin burada doğru olup olmadığından tam olarak emin değilim, ama Haskell'de açgözlü bir zip işlevi olup olmadığını merak ediyordum. Bu benim zip' açgözlü zip fonksiyonudur Haskell'in açgözlü bir zip (biri tüm öğeleri koruyan) var mı?

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

... olsaydı, o küpe uzun liste bir elemana sahip uzun listenin uzunluğu ve listesini döndürür, ama daha kısa olacağı anlamına gelir Liste Nothing, ilgili parça pozisyonuna getirilmez. Bunu nasıl yazacağımı sormuyorum, fakat bunun bir yerleşik olarak var olup olmadığını merak ediyordum.

İşte (özel ayrılmasıdır Either aksine,) Açgözlü fermuar düzgünce münhasır olmayan ayrılma türü ile ifade edilebilir (muhtemelen büyük değil) benim uygulaması

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 
+1

İmzayla arama. –

+0

@KarolyHorvath Üzgünüm. Ne demek istediğini anlamadım. –

+0

https://www.haskell.org/hoogle/ –

cevap

34

olduğunu. İki popüler paket bunu sunuyor. Biri minimalist, bağımlılık içermeyen 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] 

diğer these olan çan ve ıslık dolu gelir: (Maybe a, Maybe b) daha da niyet iyi ifade

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] 
Ben Or a b inanıyoruz

ve These a b (İkinci tip, açgözlü bir zip asla üretmeyecek olan (Nothing, Nothing) içerir. Yine de, her iki zipOrWith

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) 

... ya alignWith ... Data.Or den Data.Align gelen kullanarak zip' ifade edebilir:

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, aslında, padZip adı altında senin fonksiyonunu sağlar .

+1

Vay! 'Veya' daha iyi bir fikir. Çok teşekkür ederim! –

+2

Görünüşe göre 'align' istenen işlevi tam olarak sağlıyor - padZip :: Align f => fa -> fb -> f (Belki a, Belki b) '- ama dediğiniz gibi, 'Ya da' niyetini ifade eder (belki de belki de b) 'den daha iyidir. – user2407038

+0

@ user2407038 Çok iyi tespit edildi. Bunu cevaba ekledim; teşekkür ederim. – duplode