2009-12-20 37 views
10

bir yapıya "açmak" Nasıl Geçenlerde bu sorun üzerinde geldi ve bir çözüm buldum ama daha iyi (ya da sadece daha deyimsel) çözümler olup olmadığını merak ediyorum.Haskell

Bir renk için bir yapıya sahiptir:

data Rgb = Rgb Double Double Double 

Ve Kahire'den aslında tek tek renk bileşenleri geçmek istediğiniz bir işlevi vardır:

setSourceRGB :: Double -> Double -> Double -> Render() 

yüzden gerek Bu veri yapısını bir şekilde açmak için, setSourceRGB bir Rgb almaz. İki yol buldum. Sonra Yapabileceğim

applyRgb :: (Double -> Double -> Double -> t) -> Rgb -> t 
applyRgb f (Rgb r g b) = f r g b 

: biri, bir Rgb içeriğini uygulamak için bir işlev tanımlamaktır

applyRgb setSourceRGB rgb 

Bir dava ile bir satır içi Lambda ifade yapmaktır ile geldi başka yolu da, bir şekilde doğru görünmüyor sadece bazı değerler geçirmek için bir işlev uygulayarak,

(\z -> (case z of (Rgb r g b) -> setSourceRGB r g b)) rgb 

Ancak bu tamamen mutlu değilim: Ben ayrı işlevi tanımlamak gerekmez anlamına gelir. Ben bunu tersine çevirmek mümkün ister ve setSourceRGB için doğru türüne Rgb "dönüştürmek" olur. Ne yazık ki bana öyle geliyor ki bu bir fonksiyonu setSourceRGB geçirilebilir

fromRgb :: Rgb -> Double -> Double -> Double 

olması imkansızdır bu. Belki applyRgb en iyi çözümdür, ama bana bunu ifade sağlayacak bazı iyi bir yolu olup olmadığını merak ediyorum:

setSourceRGB (fromRgb rgb) 
+3

? '(\ (RGB Rg b) -> SetSource Rg b) – ephemient

cevap

3

Hayır, setSourceRGB (fromRgb rgb) gibi bir şey yazamıyor, bu olacak çünkü Sadece işleve bir argüman verin, böylece applyRgb en iyi çözüm gibi görünüyor. Eğer bu tür bir şey gibi, aynı zamanda bir infix fonksiyonu olarak applyRgb kullanabiliyorsanız:

setSource `applyRgb` rgb 

sık sık bu işlevi kullanırsanız, sizin applyRgb setSource için bir isim tanımlayarak okumak için kod kolaylaştırabilir. yerine

data Rgb = Rgb !Double !Double !Double 

ve -funbox-sıkı-alanlarla derlemek, böylece bileşenler tahsisi içermeyen ilkel çift değerlere çözdükten edilebilir:

4

BTW, neredeyse kesinlikle sahip olmalıdır.

2

Sen fonksiyonunu kendisi çözdüm yolları sarma olmadan birden argümanları içine bir şey "açmak" olamaz.

Ancak tutarlılık için, muhtemelen bu gibi yardımcı bir isim olurdu.

of` .. `dava ile ne var
-- from Prelude... 
uncurry :: (a -> b -> c) -> (a, b) -> c 
uncurry f (a, b) = f a b 

-- yours? 
uncurryRgb :: (Double -> Double -> Double -> a) -> Rgb -> a 
uncurryRgb f (Rgb r g b) = f r g b 
+0

Eğer imza eşleşecek şekilde tanımı düzeltmek gerekir rgb'. Şu an davalar farklı. – Martijn

+0

Augh, yazım hatası. Eh, farklılıklar yazım bir yana, bu OP'nin 'applyRgb' ile aynı tanımdır ... – ephemient