2016-11-26 1 views
0

Ich versuche, zwei polymorphe Tupel paarweise zu addieren. (Die Typen des ersten Elements in einem Tupel sollte die gleiche wie die erste in der zweiten und ebenfalls für das zweite Element sein) Hier ist mein Code:Erstellen einer Koordinatenklasse in Haskell

module Main where 

class Coordinate a where 

    createCoordinate :: a 

    getFirst :: (a,b) -> a 

    getSecond :: (a,b) -> b 

    addCoordinates :: (a,b) -> (a,b) -> (a,b) 

instance Coordinate() where 

    createCoordinate =() 

    getFirst (a,b) = a 

    getSecond (a,b) = b 

    addCoordinates a b = (getFirst a + getFirst b, getSecond a + getSecond b) 

Also, das Problem ist, mit meiner addCoordinates Funktion. Ich habe mich gefragt, ob mir jemand helfen könnte, wie man die Funktion implementiert. Danke! :)

+0

Ja, ich Haskell bin sehr neu. Meine vorherige Programmiererfahrung wäre mit Java gewesen. Gibt es etwas Spezifisches, das ich für dich klären könnte? –

+0

Warum arbeiten alle Klassenfunktionen an Tupeln und nicht an Koordinaten? Was ist der Zweck der 'b' Typ Variable, die die meisten Ihrer Methoden haben - wie warum arbeiten Sie mit Tupeln, bei denen das erste Element eine Koordinate ist und das zweite Element willkürlich ist? Und wie macht es Sinn, dass der Einheitswert eine Koordinate ist? – sepp2k

+0

Ich glaube nicht, dass Sie hier eine 'Klasse' wollen. Sie möchten nicht, dass sich beliebige Typen wie Koordinaten verhalten. Sie möchten einen Datentyp, der ein Wertepaar enthält. – pat

Antwort

4

Sie wahrscheinlich einen Datentyp mögen, keine Klasse:

data Coordinate a b = Coordinate { getFirst :: a, getSecond :: b } 
    deriving (Eq, Ord, Show) 

Ihre Funktionen wären dann:

createCoordinate :: a -> b -> Coordinate a b 
createCoordinate a b = Coordinate a b 

addCoordinates :: (Num a, Num b) => Coordinate a b -> Coordinate a b -> Coordinate a b 
addCoordinates (Coordinate a1 b1) (Coordinate a2 b2) = Coordinate (a1+a2) (b1+b2) 

Beachten Sie, dass a und b von jeder Art sein können, aber addCoordinates funktioniert nur, wenn sie Instanzen von Num sind, weil wir + auf sie anwenden möchten. Sie benötigen keine Typklasse, um Coordinate zu definieren.

A typeclass Sie erlauben würde, die Dinge zu definieren, die Werte zum Beispiel initialisiert werden kann, um den Standard:

class DefaultInitializable a where 
    defaultInit :: a 

Wir haben dann Int eine Instanz dieser Klasse machen können:

instance DefaultInitializable Int where 
    defaultInit = 0 

Und wir können make Coordinate eine Instanz, solange ihre Parameter auch Instanzen sind:

instance (DefaultInitializable a, DefaultInitializable b) => DefaultInitializable (Coordinate a b) where 
    defaultInit = Coordinate default default 
+0

Ich habe versucht, dies als eine Übung, um über Klassen zu lernen, ich denke, das oben wäre wahrscheinlich eine gute Lösung, aber ich weiß nicht, ob es wirklich hilft mir lernen über polymorphe Klassen und Implementierungen Instanzen dieser Klassen. Danke für Ihre Hilfe. –

+0

Sie könnten eine Klasse für Dinge erstellen, die standardmäßig initialisiert werden können, und sie zum Implementieren von createCoordinate verwenden (vorausgesetzt, a und b sind standardmäßig initialisierbar). – pat

+0

Ich bin nicht wirklich sicher, dass ich verstehe, was Sie standardmäßig initialisiert meinen, könnten Sie das bitte erklären? –

0

Ich fühle mich dies eine Lösung sein könnte, was ich wollte

module Main where 

class Coordinate c where 

    createCoordinate :: x -> y -> c x y 

    getFirst :: c x y -> x 

    getSecond :: c x y -> y 

    addCoordinates :: (Num x) => (Num y) => c x y -> c x y -> c x y 

instance Coordinate (,) where 

    createCoordinate a b = (a,b) 

    getFirst (a,_) = a 

    getSecond (_,b) = b 

    addCoordinates a b = (getFirst a + getFirst b, getSecond a + getSecond b) 
+0

Aber die Frage steht, _Was verdient diese Klasse Sie_ gegenüber einfach mit geeigneten Funktionen auf einfache monomorphe '(a, b)' Tupel? Oder in der Tat eine _vector Klasse wie ['R2'] (http://hackage.haskell.org/package/linear-1.20.5/docs/Linear-V2.html#t:R2), noch besser [' VectorSpace'] (http://hackage.haskell.org/package/vector-space-0.10.4/docs/Data-VectorSpace.html#t:VectorSpace), die sicherstellen, dass die Elemente einheitlich behandelt werden. Trotzdem denke ich, dass die Idee für ganz andere Anwendungen nützlich sein könnte; das hat mich [zu einer neuen Frage] inspiriert (http://stackoverflow.com/questions/40835094/). – leftaroundabout

Verwandte Themen