2014-04-02 9 views

Antwort

15

Als Erweiterung zu Standard Haskell können Sie mit "Arten" umgehen. Arten sind ein sehr einfaches Typsystem für Typen und Typkonstruktoren. Art * ist ein einfacher Typ, wie Int. Kind * -> * ist ein Typkonstruktor, der einen Typ annimmt und einen Typ ergibt, wie Maybe: übergeben Sie einen Typ wie Int als ein Argument, und Sie erhalten den Typ Maybe Int.

Die andere Erweiterung in diesem Code (die ich nicht bemerkt habe, seit der Einzug verloren wurde) ist Typen zugeordnet. Eine Typklasse in Standard-Haskell kann eine Reihe von Funktionen angeben, die der Typ unterstützen muss. Bei zugeordneten Typen können zusätzlich Typen und Typkonstruktoren angegeben werden, die dem Typ zugeordnet sind.

Hier bedeutet dies, dass ein Typ i, die eine Instanz von Imageable ist (d.h. wie ein Bild verhält) Pixel i einen zugehörigen Pixeltyp aufweisen müssen, und dies muss eine einfache Art (Art *), nicht einen Typkonstruktor.

+0

Wissen Sie, warum der Codeautor dieses Design verwendet? – osager

+2

Es gibt nicht viel Auswahl. Sie haben eine Art von Typ, die ein Bild darstellt, und die Typklasse benötigt Funktionen, die sich mit einem einzelnen Pixel im Bild befassen. Sie müssen einen Weg finden, um herauszufinden, welcher Typ dieses Pixel ist. Du könntest es reparieren, aber das ist nicht sehr flexibel. Sie könnten Imageable zu einer Multi-Param-Klasse über dem Bild und dessen Pixel machen, aber dann brauchen Sie funktionale Abhängigkeiten oder Typ-Ambiguitäten werden Sie verrückt machen, und Sie müssen immer noch den Pixel-Typ in jeder Signatur erwähnen, die die Klasse verwendet. Zugehörige Typen sind viel sauberer und einfacher. –

1

"Also Pixel ist eine Funktion?"

Pixel ist eine Typ-Level-Funktion. Es benötigt einen einzelnen Typ (der eine Instanz von Imageable sein muss) und gibt einen Typ vom Typ '*' zurück. Aufgrund seiner Verwendung im Beispielcode muss der Eingabetyp ebenfalls vom Typ '*' sein. Also, Pixel ist sehr ähnlich zu Maybe, sie sind beide "Typkonstruktoren" der Art "* -> *", Sie geben ihnen einen "einfachen Typ" und sie geben einen "einfachen Typ" zurück. Sie gelten auch an den gleichen Orten. Genauso wie Sie keine Funktion vom Typ 'Foo -> Maybe' haben können, können Sie auch keine Funktion vom Typ 'Bar -> Pixel' haben.

+0

Also das 'type' Schlüsselwort ist nicht wie bei einem Haskell Type Synonyms Schlüsselwort richtig? Wenn es so ist, wie du gesagt hast, warum ist es nicht so geschrieben: 'type Pixel :: i -> *' – osager

+1

@osager Es ist verwandt, aber nicht dasselbe. Wenn Sie eine Instanz (Imagable my_image) bereitstellen, muss Ihre Definition für Pixel ein vorhandener Typ sein und (Pixel my_image) ist ein Alias ​​/ Synonym für diesen Typ. Es handelt sich um eine GHC-Erweiterung, die als (offene) Familien bezeichnet wird. –