我是 Haskell 新手,所以我很可能错过了一些明显的东西......
我正在尝试使用临时多态性编写通用颜色量化算法。但是,我在通过模式匹配获取数据时遇到了一些麻烦(我实际上还没有接触到量化位)。
我无法简洁地描述这一点,所以这是我的代码的简化版本,它显示了这个问题:
{-# LANGUAGE FlexibleInstances #-}
import Data.Word
type ColourGrey = Word8
data ColourRGB = ColourRGB Word8 Word8 Word8
deriving (Show)
data ColourStream = Greys [ColourGrey]
| Colours [ColourRGB]
deriving (Show)
class Colour a where
extractStreamData :: ColourStream -> [a]
instance Colour ColourGrey where
extractStreamData (Greys x) = x
instance Colour ColourRGB where
extractStreamData (Colours x) = x
someColours = Colours [ColourRGB 255 0 0, ColourRGB 0 255 0, ColourRGB 0 0 255]
someGreys = Greys [0, 127, 255]
main :: IO ()
main = do
print $ extractStreamData someColours
print $ extractStreamData someGreys
extractStreamData
失败的调用如下:
No instance for (Colour a1)
arising from a use of `extractStreamData'
The type variable `a1' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Note: there are several potential instances:
instance Colour ColourRGB -- Defined at test.hs:20:10
instance Colour ColourGrey -- Defined at test.hs:17:10
In the second argument of `($)', namely
`extractStreamData someGreys'
In a stmt of a 'do' block: print $ extractStreamData someGreys
In the expression:
do { print $ extractStreamData (someColours :: ColourStream);
print $ extractStreamData someGreys }
对我来说,这意味着 Haskell 无法推断要使用哪个实例(一个用于颜色或一个用于灰度)。那是对的吗?如果是这样,我将如何解决这个问题?
注意ColourGrey
和的定义ColourRGB
超出了我的影响范围(它们是外部库的一部分)。所以任何建议都需要以这两种类型为模。我也不想乱用ColourStream
,因为它在许多其他地方都使用过。
我需要访问“原始”列表的原因是我可以使用诸如map
等之类的东西。如果有一个我还没有学习的巧妙技巧可以使ColourStream
迭代,那么我想那会奏效......</thinking aloud>