如何在haskell中"解包"一个结构

Ste*_*eve 10 struct haskell ffi

我最近遇到了这个问题并找到了解决方案,但我想知道是否有更好的(或更恰当的)解决方案.

我有一个颜色的结构:

data Rgb = Rgb Double Double Double
Run Code Online (Sandbox Code Playgroud)

还有一个功能我想将颜色组件单独传递给实际上来自开罗:

setSourceRGB :: Double -> Double -> Double -> Render ()
Run Code Online (Sandbox Code Playgroud)

所以我需要以某种方式"解包"这个数据结构,因为setSourceRGB不需要Rgb.我找到了两种方法.一种是定义一个函数来应用以下内容Rgb:

applyRgb :: (Double -> Double -> Double -> t) -> Rgb -> t
applyRgb f (Rgb r g b) = f r g b
Run Code Online (Sandbox Code Playgroud)

然后我可以这样做:

applyRgb setSourceRGB rgb
Run Code Online (Sandbox Code Playgroud)

我想出的另一种方法是使用case进行内联lambda表达式,这意味着我不必定义单独的函数:

(\z -> (case z of (Rgb r g b) -> setSourceRGB r g b)) rgb
Run Code Online (Sandbox Code Playgroud)

我对此并不完全满意,但是以某种方式应用函数只是为了传递一些值似乎并不正确.我希望能够扭转它,并将其"转换" Rgb为正确的类型setSourceRGB.不幸的是,在我看来,拥有一个功能是不可能的

fromRgb :: Rgb -> Double -> Double -> Double
Run Code Online (Sandbox Code Playgroud)

可以传递给setSourceRGB.也许applyRgb是最好的解决方案,但我想知道是否有更好的方法可以让我表达为:

setSourceRGB (fromRgb rgb)
Run Code Online (Sandbox Code Playgroud)

Don*_*art 5

顺便说一句,你几乎肯定应该有:

data Rgb = Rgb !Double !Double !Double
Run Code Online (Sandbox Code Playgroud)

相反,并使用 -funbox-strict-fields 进行编译,因此可以将组件解压缩为无分配的原始双精度值。


gno*_*ain 3

不,你不能写像 setSourceRGB (fromRgb rgb) 这样的东西,因为它只会给函数一个参数,所以 applyRgb 似乎是最好的解决方案。如果你喜欢这种东西,你也可以使用 applyRgb 作为中缀函数:

setSource `applyRgb` rgb
Run Code Online (Sandbox Code Playgroud)

如果您经常使用此函数,可以通过为 applyRgb setSource 定义一个名称来使代码更易于阅读。