gpt4 book ai didi

image - 使不需要的转换成为无操作

转载 作者:行者123 更新时间:2023-12-02 20:42:21 24 4
gpt4 key购买 nike

我正在编写一个程序,它可以读取和写入支持多种像素类型(即 RGB、CMYK、灰度等)的图像。这些像素类型可以使用不同类型的组件,有点像这样:

class (Storable c) => PixelComponent c where
blackWhite :: c -> (c, c)
toInt :: c -> Int
toRealFrac :: (RealFrac a) => c -> a
fromComponent :: (PixelComponent a) => a -> c

instance PixelComponent CUChar where
blackWhite x = (minBound x, maxBound x)
toInt = id
toRealFrac = fromIntegral
fromComponent x = ???

instance PixelComponent CFloat where
black = 0.0
white = 1.0
toInt = truncate
toReal = id
fromComponent x = ???

class (Storable pix) => Pixel pix where
red :: pix c -> c
green :: pix c -> c
blue :: pix c -> c
alpha :: pix c -> c
luminance :: pix c -> c
fromPixel :: (Pixel a) => a c -> pix c

这个想法是,您应该能够执行 getPixel myImage (10, 23)::RGB CUChargetPixel myImage (10, 23)::RGB CFloat取决于您想要的像素格式。问题是我不知道如何以有效的方式实现 fromComponent 。本质上,我希望诸如 fromComponent (1::CUChar)::CUCharfromComponent (0.5::CFloat)::CFloat 等不必要的转换成为无操作。我想无论如何我都必须依赖优化。

注意:无论如何,这可能不是一个好的设计,所以如果有人有更好的建议,我对此持开放态度。我仍然想知道如何使这个解决方案发挥作用。

最佳答案

我建议以与 GHC 处理数字转换相同的方式处理此问题(例如 fromIntegral),即通过重写规则。

如果你查看GHC.Real ,你发现

-- | general coercion from integral types
fromIntegral :: (Integral a, Num b) => a -> b
fromIntegral = fromInteger . toInteger

{-# RULES
"fromIntegral/Int->Int" fromIntegral = id :: Int -> Int
#-}

默认情况下,整型类型会进行大量往返,但幸运的是,这种情况永远不会发生,因为所有库提供的整型类型都有规则。

GHC.Int 中指定了更多规则例如处理其余的转换。您会发现其他类似函数的类似设置(例如 realToFrac)。

现在您的用例存在一个主要问题,即规则通常很难匹配类方法。有两种方法可以解决这个问题。第一个是定义一个通用类型(例如 GHC 代码中的 Integer),并提供与该类型相互转换的类方法。然后编写一个通用转换函数(例如 fromIntegral),在任何地方使用它,并让您的规则与其匹配。

另一种方法是这样做:

instance PixelComponent CUChar where
blackWhite x = (minBound x, maxBound x)
toInt = id
toRealFrac = fromIntegral
{-# INLINE fromComponent #-}
fromComponent = toCUChar

toCUChar :: PixelComponent a => a -> CUChar
toCUChar = ...

{-# RULES "fromComponent/CUChar->CUChar" toCUChar = id :: CUChar -> CUChar #-}

前者是 GHC 所做的,所以它可能工作得很好。我最近一直在使用后一种方法,但没有遇到任何问题,因此任何一种方法都应该有效。

关于image - 使不需要的转换成为无操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21747602/

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