10

私は最近この問題に遭遇し、解決策を見つけましたが、より良い(またはより慣用的な)解決策があるかどうか疑問に思っています。

私は色の構造を持っています:

data Rgb = Rgb Double Double Double

そして、実際にはカイロから、色成分を個別に渡したい関数があります。

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

setSourceRGBしたがって、をとらないので、このデータ構造を何らかの方法で「解凍」する必要がありRgbます。私は2つの方法を見つけました。Rgb1つは、 :の内容を適用する関数を定義することです。

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

それから私はすることができます:

applyRgb setSourceRGB rgb

私が思いついたもう1つの方法は、ケースを使用してインラインラムダ式を実行することです。これは、別の関数を定義する必要がないことを意味します。

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

私はこれに完全に満足しているわけではありませんが、どういうわけか、いくつかの値を渡すためだけに関数を適用することは正しくないようです。私はそれを好転させてRgb、の正しいタイプに「変換」できるようにしたいと思いsetSourceRGBます。残念ながら、機能を持つことは不可能だと私には思えます

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

に渡すことができますsetSourceRGB。おそらくapplyRgb最善の解決策ですが、それを次のように表現できるより良い方法があるかどうか疑問に思っています。

setSourceRGB (fromRgb rgb)
4

3 に答える 3

5

ところで、ほぼ確実に次のものが必要です。

data Rgb = Rgb !Double !Double !Double

代わりに、-funbox-strict-fields でコンパイルして、コンポーネントを割り当てのないプリミティブ double 値にアンパックできるようにします。

于 2009-12-20T04:30:04.073 に答える
3

いいえ、setSourceRGB(fromRgb rgb)のようなものを書くことはできません。これは、関数に1つの引数を与えるだけなので、applyRgbが最善の解決策のようです。この種のものが好きな場合は、applyRgbを中置関数として使用することもできます。

setSource `applyRgb` rgb

この関数を頻繁に使用する場合は、applyRgb setSourceの名前を定義することで、コードを読みやすくすることができます。

于 2009-12-20T00:46:33.917 に答える