I recently came across this problem and found a solution but I'm wondering if there are better (or just more idiomatic) solutions.
I have a structure for a colour:
data Rgb = Rgb Double Double Double
And there is a function I'd like to pass the colour components to individually, actually from Cairo:
setSourceRGB :: Double -> Double -> Double -> Render ()
So I need to "unpack" this data structure somehow, since setSourceRGB
doesn't take an Rgb
. I found two ways. One is to define a function to apply the contents of an Rgb
:
applyRgb :: (Double -> Double -> Double -> t) -> Rgb -> t
applyRgb f (Rgb r g b) = f r g b
Then I can do:
applyRgb setSourceRGB rgb
Another way I came up with is to do an inline lambda expression with a case, which means I don't have to define a separate function:
(\z -> (case z of (Rgb r g b) -> setSourceRGB r g b)) rgb
I'm not completely happy with this however, somehow applying a function just to pass some values doesn't seem right. I'd like to be able to turn it around, and "convert" the Rgb
to the right type for setSourceRGB
. Unfortunately it seems to me that's it's impossible to have a function
fromRgb :: Rgb -> Double -> Double -> Double
that can be passed to setSourceRGB
. Perhaps applyRgb
is the best solution, but I'm wondering if there's some better way that will let me express it as:
setSourceRGB (fromRgb rgb)
BTW, you should almost certainly have:
data Rgb = Rgb !Double !Double !Double
instead, and compile with -funbox-strict-fields, so the components can be unpacked into allocation-free primitive double values.
No, you can't write something like setSourceRGB (fromRgb rgb), because it will just give one argument to the function, so applyRgb seems like the best solution. If you like this sort of thing, you can also use applyRgb as an infix function :
setSource `applyRgb` rgb
If you often use this function, your can make your code easier to read by defining a name for applyRgb setSource.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With