2017-03-14 5 views
0

Ich bin ein Anfänger in Haskell und ich versuche, ein Element am Ende einer Liste hinzuzufügen.Fügen Sie ein Element am Ende der Liste in Haskell

Ich gebe eine Liste wie [1,2,3,4] und eine Nummer 10 ein. Ich möchte eine Ausgabe wie diese [1,2,3,4,10].

Mein Code:

func a [] = a 
func a (x:xs) = x : func a (x:xs) 

Aber ich bin diesen Fehler bekommen:

Non type-variable argument in the constraint: Num [a] 
(Use FlexibleContexts to permit this) 
When checking that ‘it’ has the inferred type 
it :: forall a. (Num a, Num [a]) => [a] 

jedermann mit einer Erklärung helfen?

+0

Das Hinzufügen eines Elements zum Ende einer Liste ist eine gute Übung, aber normalerweise sollten Sie es nicht in echten Haskell-Programmen tun. Es ist teuer und zeigt an, dass Sie Ihre Liste in der falschen Reihenfolge erstellen. Es gibt normalerweise einen besseren Ansatz. – amalloy

+0

Es ist nur eine Übung für das College :) – Darius

Antwort

1

Sie müssen verstehen, dass das, was passiert mit Ihren Definitionen der Funktionen auf der linken Seite des Gleichheitszeichens ist "pattern matching".

Mit der folgenden Anweisung, Sie sagen, im Grunde

func a [] = a 
... 

Ich möchte zunächst ein Element von jeder Art, dh a, als ersten Parameter und eine leere Liste als zweiten Parameter zu akzeptieren, dh [] . Wenn das der Fall ist, möchten Sie a zurückgeben. Das Problem ist, dass Sie eine Liste [a] zurückgeben möchten (Sie werden später in dieser Antwort sehen, warum).

Mit dem zweiten Teil Ihrer Funktionsdefinition (das bedeutet, dass das erste "Muster" nicht mit Ihren Eingaben übereinstimmt) sagen Sie: Ich akzeptiere ein Element eines beliebigen Typs, dh a, und eine nicht leere Liste , dh (x:xs). (x:xs) ist eine Möglichkeit zu sagen: ok, ich habe eine Liste und x ist das erste Element dieser Liste. Der Rest der Liste rufe ich xs, die leer sein könnte; In diesem Fall wäre Ihre ursprüngliche Liste eine Liste der Größe eins, d. h. nur [x].

... 
func a (x:xs) = x : func a (x:xs) 

Was Sie zurück, wenn das Muster abgestimmt ist

... = x : func a (x:xs) 

was bedeutet, dass Sie das erste Element der Liste als zweiten Parameter übergeben sind unter (dh x) und das Voranstellen es die Ergebnis von func a (x:xs).

diese Beschreibung Ihres Problems gegeben, hier ist eine mögliche Lösung:

func a [] = [a] 
func a (x:xs) = x : func a xs 

ich hier zwei Dinge beachten mag. In dem ersten Muster, d. H. func a [] = [a], gebe ich eine Liste zurück, d. H. [a]. In dem zweiten Muster übertrage ich xs an func, d. H. func a xs. In beiden Fällen gebe ich eine Liste zurück!

Warum funktioniert das? Schauen wir uns ein Beispiel an. Nehmen wir an, Sie rufen func wie func 3 [1, 2]. Dann würde das passieren.

Da [1, 2] keine leere Liste ist, stimmen Sie nicht mit dem ersten Muster überein, also lassen Sie uns die zweite sehen; ja, wir passen gegen die zweite. Jetzt haben wir das a = 3, x = 1 (der Anfang der Liste) und xs = [2]. So haben wir dann 1 : func 3 [2]. Also wir rekrutieren! Wir haben jetzt a = 3 (wie zuvor), und xs = [] (d. H. Eine leere Liste). Also fahren wir mit dem Funktionskörper fort und machen 2 : func 3 []. Schließlich passt func 3 [] mit dem ersten Muster und Sie geben [3] zurück. Aber zu was? Nun, zu 2 : [3], was zu was zurück? Zu 1 : 2 : [3].

1

vergleichen:

func a (x:xs) = x : func a (x:xs) 
     --  ^^^^^^^^^^^^^^^^^ returns a list 
func a [] = a 
     --^returns a non-list 

daher den Typ Fehler. Wahrscheinlich möchten Sie stattdessen [a] oder a : [].

(Des Weiteren ist der rekursive Aufruf falsch, da Sie wieder die ganze Liste übergeben x:xs drin. Die Liste Sie kleinere sonst bekommen sollte nie den Basisfall erreichen.)

Verwandte Themen