首先,如果此问题已经被提出,我很抱歉,我只是找不到合适的英语术语来表达我的意思。
我想知道在Haskell中是否有任何类型类来表示函数应用程序,以便为不同的数据类型定义多个行为。
使用
我想知道在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
uncurry :: (a -> b -> c) -> ((a, b) -> c)
了吗? - mb21uncurry
应用于元组中的每个函数?组合uncurry
N次并不是真正的解决方案,因为我们仍然需要为每个函数复制相同的代码。 - Lilymonadedsp
函数可以像curry
和uncurry
一样正常地作为普通的帮助函数(helper function)工作 - 您不需要为此创建一个类型类。也许可以参考http://learnyouahaskell.com/higher-order-functions#curried-functions。 - mb21x y -> f
而不是f x -> y
或者f -> x, f -> y
有点令人惊讶。 - leftaroundaboutdspX
函数 ^^ @leftaroundabout 我对 fundep 完全不熟悉,也不知道该如何决定使用哪个 fundep。 - Lilymonade