gpt4 book ai didi

haskell - 如何在 Haskell 中使用 "overload"美元运算符

转载 作者:行者123 更新时间:2023-12-02 10:08:58 24 4
gpt4 key购买 nike

首先,很抱歉,如果这个问题已经被问到,我只是找不到合适的英语术语来表达我的意思。

我想知道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.ApplicativeControl.Arrow但多参数函数的结果并不好。

到目前为止我最好的尝试是:(,) <$> blackPixel <*> whitePixel

最佳答案

这并不是一个真正的答案,但以下是如何将这个想法扩展到真正的“$ 运算符的重载”:

{-# LANGUAGE TypeFamilies, FlexibleInstances #-}

import Prelude hiding (($))

infixr 0 $

class Dispatch f where
type Argument f :: *
type Result f :: *
($) :: f -> Argument f -> Result f

instance Dispatch (a -> b) where
type Argument (a->b) = a
type Result (a->b) = b
f $ x = f x

instance (Dispatch x, Dispatch y, Argument x ~ Argument y)
=> Dispatch (x,y) where
type Argument (x,y) = Argument x
type Result (x,y) = (Result x, Result y)
(f,g) $ a = (f $ a, g $ a)

instance ( Dispatch x, Dispatch y, Dispatch z
, Argument x ~ Argument y, Argument y ~ Argument z )
=> Dispatch (x,y,z) where
type Argument (x,y,z) = Argument x
type Result (x,y,z) = (Result x, Result y, Result z)
(f,g,h) $ a = (f $ a, g $ a, h $ a)

main :: IO ()
main = do
print $ ((\x -> ((2*x+),(3*x+)), (**), logBase) $ 2) $ 4
((8.0,10.0),16.0,2.0)

关于haskell - 如何在 Haskell 中使用 "overload"美元运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52716056/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com