Что означает звезда в этом кодеке Хеккеля?

Я нашел этот код в пакете unm-hip. Итак, Pixel - это функция?

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)]]

Ответ 1

Как расширение стандартного Haskell, вы можете заниматься "видами". Виды - это очень простая система типов для типов и типов конструкторов. Вид * - это простой тип, например Int. Вид * -> * - это конструктор типа, который берет тип и дает тип, например Maybe: передайте ему тип типа Int в качестве аргумента, и вы получите тип Maybe Int.

Другое расширение, используемое в этом коде (которое я не заметил сначала, так как отступ был утерян) - это связанные типы. Стандартный класс в стандартном Haskell может указывать ряд функций, которые должен поддерживать тип. Со связанными типами он может дополнительно указать типы и типы конструкторов, которые связаны с типом.

Здесь это означает, что тип i, являющийся экземпляром Imageable (т.е. ведет себя как изображение), должен иметь связанный тип пикселя Pixel i, и это должен быть простой тип (вид *), а не конструктор типа.

Ответ 2

"Итак, Pixel - это функция?"

Пиксель - это функция уровня. Он принимает один тип (который должен быть экземпляром Imageable) и возвращает тип вида '*'. Исходя из этого использования в примере кода, тип ввода также должен иметь вид "*". Итак, Pixel очень похож на Maybe, они оба являются "конструкторами типов" вида "* → *", вы предоставляете им "простой тип", и они возвращают "простой тип". Они также действительны в тех же местах. Так же, как вы не можете иметь функцию типа "Foo → Maybe", вы также не сможете использовать функцию типа "Бар → Пиксель".