Прежде всего, извините, если этот вопрос уже задавался, я просто не мог найти правильные английские термины, чтобы выразить то, что я имел в виду.
Мне было интересно, был ли какой-нибудь класс типов в Haskell, представляющий функциюприложение, чтобы определить несколько поведения для разных типов данных.
Используя пакет Graphics.X11.Xlib
, я натолкнулся на множество различных функций, запрашивающих одинаковые параметры.Таким образом, моя идея заключалась в том, чтобы упаковать эти функции в кортеж (поскольку их тип возврата не совпадает) и передать им все параметры сразу.Примерно так:
import Graphics.X11.Xlib
main = do
display <- openDisplay ":0"
let dScreen = defaultScreen display
(black, white, cMap) =
-- here is where the "parameter dispatch" is needed
(blackPixel, whitePixel, defaultColormap) display dScreen
-- computation
return ()
Я ничего не нашел, поэтому я решил создать этот тип класса:
{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, FunctionalDependencies #-}
import Graphics.X11.Xlib
class Dispatch f x y | x y -> f where
dsp :: f -> x -> y
instance Dispatch (a -> b, a -> c, a -> d) a (b, c, d) where
dsp (f, g, h) x = (f x, g x, h x)
main = do
display <- openDisplay ":0"
let dScreen = defaultScreen display
(black, white, cMap) =
-- here is where the "parameter dispatch" is needed
(blackPixel, whitePixel, defaultColormap) `dsp` display `dsp` dScreen
-- computation
return ()
Он отлично работает и умножает экземпляры для разных кортежей.размеров, можно просто добавлять или удалять функции из «кортежа функций» в зависимости от необходимых значений, и код все равно будет компилироваться.
Но есть ли способ сделать это без этого обходного пути?Я пытался использовать Control.Applicative
или Control.Arrow
, но функции с несколькими параметрами плохо заканчиваются.
Моя лучшая попытка на данный момент: (,) <$> blackPixel <*> whitePixel