2017-10-14 1 views
0

Ich kann diese Methode überhaupt nicht funktionieren. Immer Fehler bekommen. Wo mache ich einen Fehler? Es soll String-Array von Zahlen akzeptieren, den Kopf nehmen, einen Punkt erstellen. Ich denke jedoch, dass das Problem im Rekursionsaufruf liegt.Haskell zurück benutzerdefinierte Datentyp

data Point = Point(Int, Int) -- y, x 
instance Show Point where 
    show (Point(y, x)) = "(" ++ show x ++ "," ++ show y ++ ")" 

gimmePoints :: String -> Point      
gimmePoints (x:xs) = do Point(1,2) 
         gimmePoints xs 
+0

Was meinst du mit "String-Array von Zahlen", vorausgesetzt, dass der Point-Konstruktor zwei Zahlen nimmt? Wie sind sie getrennt? – Tobias

+0

'Point' hat keine' Monad' -Instanz, daher kann 'do'-Notation nicht verwendet werden. Ihr "Point" -Typ umschließt die Koordinaten doppelt. Es ist nicht notwendig, die zwei Punkte in einem Tupel zu kapseln; Sie können einfach vom 'Point'-Konstruktor selbst umschlossen werden:' data Point = Point Int Int'. – chepner

+0

Lernst du Haskell basierend auf einem Tutorial? Denn die "gimmePoints" -Funktion macht, um ehrlich zu sein, wenig Sinn. Es ist nicht klar, was es überhaupt tun soll, geschweige denn, was es tatsächlich tut. Ich schlage vor, langsamer zu werden und eine einfachere Aufgabe zu versuchen, vielleicht eher im Einklang mit einem Haskell-Führer für Anfänger wie [LYAH] (http://learnyouahaskell.com/chapters). –

Antwort

3

Wenn Ihre Funktion Signatur ... -> Point, das bedeutet, dass das Ergebnis ein Punkt sein sollte. Nichts anderes. So können Sie sicherlich schreiben

gimmePoints :: String -> Point      
gimmePoints (x:xs) = Point(1,2) 

Das bedeutet natürlich nur das erste Zeichen in der Zeichenfolge verarbeitet werden. In der Tat, da Sie nicht wirklich Gebrauch machen das Zeichen oder irgendetwas anderes in der Zeichenfolge in irgendeiner Weise könnten Sie auch diese schreiben als

gimmePoints _ = Point(1,2) 

Ich glaube nicht, dass das, was Sie wollen.

do Syntax jedenfalls macht keinen Sinn hier, dass für ist monadischen („side-effekt“) Aktionen. Zum Beispiel, wenn Sie der Punkt für jedes Zeichen wollen auf den Bildschirm ausgegeben wird, könnten Sie

gimmePoints' (_:xs) = do 
     print $ Point(1,2) 
     gimmePoints' xs 

In diesem Fall zu tun, das Ergebnis gimmePoints wäre nicht Point überhaupt, sondern eine IO-Aktion mit nein Ergebnis (weil die „Ergebnisse“ wird auf den Bildschirm statt gesendet)

gimmePoints' :: String -> IO() 

Eine sinnvolle oder zumindest mehr funktionelle-Programmierung-ish Version Sie eigentlich wollen könnten, ist

gimmePoints'' :: String -> [Point] 
gimmePoints'' [] = [] 
gimmePoints'' (_:xs) = Point (1,2) : gimmePoints'' xs 

, d. H. Für jedes Zeichen in der Zeichenfolge ergibt sich ein Punkt im Ergebnis. Dies würde eigentlich besser geschrieben werden

+0

Vielen Dank für Ihre Erklärung. Hat funktioniert. –

Verwandte Themen