2013-06-14 15 views
24

Ich habe einige Schwierigkeiten zu verstehen, wenn in meinem Code verwenden und wenn nicht Klasse verwenden. Ich meine erstellen Sie meine eigenen, und nicht Verwendung bereits definiert Typklassen, natürlich. Mit Beispiel (sehr dummes Beispiel), sollte ich tun:Sollte ich Typklassen verwenden oder nicht?

data Cars = Brakes | Wheels | Engine 
data Computers = Processor | RAM | HardDrive 

class Repairable a where 
    is_reparaible :: a -> Bool 

instance Repairable Cars where 
    is_repairable (Brakes) = True 
    is_repairable (Wheels) = False 
    is_repairable (Engine) = False 

instance Repairable Computers where 
    is_repairable (Processor) = False 
    is_repairable (RAM)  = False 
    is_repairable (HardDrive) = True 

checkState :: (Reparaible a) => a -> ... 
checkState a = ... 

(Offensichtlich ist dies ein dummes, unvollständiges Beispiel).

Aber das ist eine Menge für einen kleinen Einsatz, nicht? Warum sollte ich nicht etwas Einfaches machen und nur Funktionen definieren, ohne neue Datentypen und Typklassen (mit ihren Instanzen) zu definieren.

Dieses Beispiel ist zu einfach, aber in Fakten sehe ich oft so etwas (neue Datentypen + Typklassen + Instanzen), wenn ich Haskell-Code auf github suche, anstatt nur Funktionen zu definieren.

Also, wenn ich neue Datentypen erstellen sollte, typeclasses etc und wann sollte ich Funktionen verwenden?

Danke.

Antwort

40

Warum ich nicht etwas einfach und nur definieren Funktionen ohne definieren, neue Datentypen und typeclasses (mit ihren Instanzen) tun soll.

Warum in der Tat? Sie könnten einfach definieren:

checkState :: (a -> Bool) -> (a -> b) -> (a -> b) -> a -> b 
checkState is_repairable repairs destroy a 
    = if (is_repairable a) then repairs a else destroy a 

Menschen missbrauchen Klassen die ganze Zeit. Es bedeutet nicht, dass es idiomatisch ist.

Um die allgemeinere Frage zu beantworten, hier sind einige Faustregeln für, wenn Typklassen zu verwenden, und wenn sie nicht verwenden:

Verwenden Typklassen, wenn:

  • nur Es ist korrektes Verhalten pro gegebenem Typ

  • Die Typklasse hat zugehörigen Gleichungen (dh „Gesetze“), dass alle Instanzen erfüllen müssen

Verwenden Typklassen nicht, wenn:

  • Sie sind nur Namespace Dinge zu versuchen. Dafür stehen Module und Namespaces.

  • Eine Person, die Ihr Typ-Klasse kann über nicht folgern, wie es ohne einen Blick auf den Quellcode der Instanzen verhalten

  • Sie feststellen, dass die Erweiterungen, die Sie müssen eingeschaltet werden außer Kontrolle geraten

+0

Yeah! Dies ist eine sehr vollständige Antwort, vielen Dank! Ihre "Klassen nicht verwenden, wenn ..." ist besonders hilfreich, um den guten Weg zu wählen, etwas zu tun. – vildric

+1

Ich würde hinzufügen, "Typklassen nicht nur für eine Methode verwenden", obwohl dies keine absolut starre Regel ist, eher wie ein allgemeiner Hinweis. – MathematicalOrchid

+2

@MathematicalOrchid Das ist ein Teil der "Bedürfnisse Gesetze" Regel, da Sie selten Gesetze für eine Typklasse mit nur einer Methode haben werden (mit Ausnahme von etwas wie 'SemiGroup', wo Sie das Assoziativitätsgesetz haben) –

5

Sie können häufig einen Datentyp anstelle einer Typklasse verwenden, z

data Repairable a = Repairable 
    { getRepairable :: a 
    , isRepairable :: Bool 
    , canBeRepairedWith :: [Tool] -> Bool -- just to give an example of a function 
    } 

Natürlich müssen Sie explizit diesen Wert zu übergeben, aber das kann eine gute Sache sein, wenn Sie mehrere Möglichkeiten haben (man denke zum Beispiel an Sum und Product wie möglich Monoid s für Zahlen). Außer, dass Sie mehr oder weniger die gleiche Ausdruckskraft wie für eine Typklasse haben.

+2

Ich bin nicht der Downvoter, aber. . . Diese Antwort beantwortet die Frage IMHO nicht wirklich. Das OP fragt, wann Typklassen verwendet werden sollen. Diese Antwort erwähnt eine Alternative zu Typklassen, sagt aber nicht, wann diese Alternative verwendet werden soll. (Wenn überhaupt, dann scheint es * ein Verständnis davon zu geben, wann Typklassen sinnvoll sind und bietet eine Alternative, die in vielen der gleichen Fälle sinnvoll ist.) – ruakh

Verwandte Themen