Недавно я столкнулся с этой проблемой и нашел решение, но мне интересно, есть ли лучшие (или просто более идиоматические) решения.
У меня есть структура для цвета:
data Rgb = Rgb Double Double Double
И есть функция, которую я хотел бы передать компонентам цвета отдельно, на самом деле из Каира:
setSourceRGB :: Double -> Double -> Double -> Render ()
Поэтому мне нужно как-то "распаковать" эту структуру данных, так как setSourceRGB
не принимает Rgb
. Я нашел два пути. Один из них - определить функцию для применения содержимого Rgb
:
applyRgb :: (Double -> Double -> Double -> t) -> Rgb -> t
applyRgb f (Rgb r g b) = f r g b
Тогда я могу сделать:
applyRgb setSourceRGB rgb
Другой способ, с которым я столкнулся, - сделать встроенное лямбда-выражение с флагом, что означает, что мне не нужно определять отдельную функцию:
(\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)