2016-09-09 6 views
3

Funktionsbeschreibung:Einfache ocaml Typ Fehler

Schreiben Sie eine Funktion any_zeroes : int list -> bool, die true zurück, wenn und nur wenn die Eingabeliste mindestens eine enthält 0

Code:

let any_zeroes l: int list = 
    List.exists 0 l 

Fehler:

This expression has type int but an expression was expected of type 
     'a -> bool 

Ich weiß nicht, warum Ocaml ist ein Problem mit den 0 hat, wenn ich l markierte ein int list zu sein. Wenn jemand mir helfen könnte, das Problem zu beheben, würde dies sehr geschätzt werden!

Danke!

+2

Verwenden Sie stattdessen 'List.mem'. –

Antwort

3

Also, zunächst einmal, du hast markieren nicht l als int list, die Syntax:

let any_zeroes l: int list 

Bedeutet, dass die any_zeroes eine Funktion ist, die ein int list zurückgibt. Ein richtiger Weg, es zu annotieren, ist die folgende:

let any_zeroes (l : int list) : bool 

Zweitens ist die Tatsache, dass Sie Marke etwas nicht die Semantik eines Programms ändern. Es ist eine Typbeschränkung, die dem Typschlussfolgerungssystem sagt, dass dieser Typ zu dem, was Sie angeben, vereinheitlicht werden soll. Wenn ein Typprüfer das nicht kann, wird er mit einem Fehler gerettet. Und Type Checker brauchen Ihre Einschränkungen nicht, sie werden meist zur besseren Lesbarkeit hinzugefügt. (Ich denke, sie werden auch von dem Kurs benötigt, den du nimmst).

Schließlich weist der Fehler Sie nicht auf die l (dass, wie Sie denken, wurde annotiert), sondern auf die 0. Und die Nachricht teilt Ihnen mit, dass die Funktion List.exists eine Funktion des Typs 'a -> bool als erstes Argument akzeptiert, aber Sie versuchen, sie mit 0 mit dem Typ int zu versorgen. Also, das Typsystem versucht, int und 'a list zu vereinheitlichen, und es gibt keine solche 'a, die int = 'a list, so dass es nicht überprüfen. Sie müssen also entweder eine Funktion übergeben oder List.mem verwenden, wie von Anton vorgeschlagen.

1

Der Typ Annotation let any_zeroes l: int list = ... bedeutet der Typ any_zeroes l ist int list; das ist nicht, was du hier meinst.

Die Anmerkung richtige Typ Ihrer Spezifikation verwendet ist:

let any_zeroes 
: int list -> bool 
= fun l -> List.exists 0 l 

In der obersten Ebene, es Feedback:

= fun l -> List.exists 0 l;; 
        ^
This expression has type int but an expression was expected of type 
    'a -> bool 

Tatsächlich ist dieser Ausdruck wegen der Art der List.exists typecheck fehlschlägt:

# List.exists;; 
- : ('a -> bool) -> 'a list -> bool = <fun> 

Das erste Argument ist ein Prädikat, das 0 ist nicht. Eine korrekte Implementierung ist:

let any_zeroes 
: int list -> bool 
= let is_zero x = x = 0 in 
    fun l -> List.exists is_zero l