2014-04-02 50 views
12

我在unm-hip包中找到了这段代码。 So Pixel是一个功能?星星在这个haskell代码中意味着什么?

class Imageable i where 
    type Pixel i :: * 
    rows :: i -> Int 
    cols :: i -> Int 
    ref :: i -> Int -> Int -> (Pixel i) 
    makeImage :: Int -> Int -> PixelOp (Pixel i) -> i 
    pixelList :: i -> [Pixel i] 
    pixelList i = [ ref i r c | r <- [0..(rows i - 1)], c <- [0..(cols i - 1)]] 

回答

15

作为标准Haskell的扩展,您可以处理“种类”。种类对于类型和类型构造函数来说是一种非常基本的类型系统。种类*是一个简单的类型,如Int。种类* -> *是一个类型构造函数,它接受一个类型并生成一个类型,如Maybe:将它传递给一个类型,如Int作为参数,并且您得到类型Maybe Int

此代码中使用的另一个扩展(我没有注意到,因为缩进丢失了)是关联类型。标准Haskell中的类型类可以指定类型必须支持的多个函数。使用关联的类型,它可以额外指定与该类型关联的类型和类型构造函数。

在此,这意味着一个类型i那就是Imageable一个实例(即行为像的图像)必须具有相关联的像素类型Pixel i,这必须是简单类型(种类*),而不是一个类型构造函数。

+0

你知道为什么代码作者使用这种设计吗? – osager

+2

没有太多的选择。你有某种代表图像的类型,而typeclass需要处理图像中单个像素的函数。你需要一些方法来找出那个像素的类型。你可以修复它,但这不是很灵活。您可以使Imageable成为图像及其像素上的多参数类型类型,但是您需要函数依赖或类型歧义会使您发疯,并且您仍然需要在使用该类的每个签名中提及像素类型。相关的类型更清洁,更容易。 –

1

“So Pixel是一种功能?”

像素是一个类型级别的函数。它需要一个类型(它必须是一个Imageable的实例)并返回一种类型'*'。根据示例代码中的用法,输入类型也必须是“*”类型。因此,Pixel非常像Maybe,它们都是类型'* - > *'的“类型构造函数”,您为它们提供了一个“简单类型”,并返回一个“简单类型”。它们在同一地点也有效。就像你不能有'Foo - > Maybe'类型的函数一样,你也不能有'Bar - > Pixel'类型的函数。

+0

所以'type'关键字不像haskell Type Synonyms关键词那么正确?如果这是你说的为什么它不是这样写的:'type Pixel :: i - > *' – osager

+1

@osager它是相关的,但不一样。当您提供(Imagable my_image)实例时,您的Pixel定义必须是现有类型,并且(Pixel my_image)将是该类型的别名/同义词。这是一个称为(开放)类型的GHC扩展。 –

相关问题