Недавно я столкнулся с этой проблемой и нашел решение, но мне интересно, есть ли лучшие (или просто более идиоматические) решения.
У меня есть структура для цвета:
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)