2012-03-25 4 views
0

Ich versuche, eine Funktion in SML zu machen, die eine Liste und einen int nimmt und gibt eine Liste aller Elemente, die weniger als die int int * int list -> int list sind ich den folgenden Code geschrieben:Weniger-als-Funktion in Standard ML

- fun less (e, L) = 
= map (fn a => if a < e then a else []) L; 

auch mit dem folgenden Code tut es Arbeit auch:

- fun less (e, L) = 
= map (fn a => if a < e then a) L; 

und der Fehler im bekommen ist:

stdIn:22.15-22.38 Error: types of if branches do not agree [overload] 
    then branch: 'Z 
    else branch: 'Y list 
    in expression: 
    if a < e then a else nil 

Ich denke, das Problem ist mit dem else Teil, aber ich weiß nicht, was ich hineinlegen soll, hat jemand einen Vorschlag? Ich sollte entweder Karten-, Falt- oder Faltfunktionen verwenden.

EDIT:

- fun less (e, L) = 
= let 
=  val acc = [] 
= in 
=  foldr (fn a => if a < e then a::acc else acc) acc L 
= end; 

noch gibt mir Fehler, die folgenden Fehler:

stdIn:241.3-241.54 Error: operator and operand don't agree [overload] 
    operator domain: 'Z * 'Y -> 'Y 
    operand:   'X -> 'X list 
    in expression: 
    foldr (fn a => if <exp> < <exp> then <exp> :: <exp> else acc) 

Antwort

1

Die Fehlermeldung ist klar; seit a hat Typ int und [] hat Typ 'a list, ihre Typen stimmen nicht überein.

Das Problem ist, dass Sie die falsche höherwertige Funktion für die Aufgabe gewählt haben. Die filter auf Listenstruktur ist hier am besten geeignet:

fun less (e, L) = filter (fn a => a < e) L 

Sie Rekursion less explizit zu implementieren verwenden könnte, oder foldl/foldr verwenden, um gefilterte Listen zu akkumulieren. Jedoch scheint map hier irrelevant zu sein.

EDIT:

Ich werde einen Hinweis geben foldl/foldr verwenden. Sie beginnen mit einer leeren Liste als Akkumulator. Stellen Sie ein Element dem Akkumulator vor, wenn dieses Element kleiner als e ist; Andernfalls den Akku zurücksenden.

EDIT 2:

Sie haben vergessen acc als Argument in der Lambda-Funktion zu übergeben: nur

fun less (e, L) = foldr (fn (a, acc) => if a < e then a::acc else acc) [] L 

Und der let..in..end Teil ist überflüssig, weil Sie [] als Akkumulator verwenden.

+0

ich sollte entweder Karte verwenden, foldl oder foldr Funktion –

+0

@ aizen92: Ich kann Ihnen nur einen Hinweis geben. Siehe meine aktualisierte Antwort. – pad

+0

was meinst du mit vorgeben? –