简体   繁体   中英

Simple ocaml type error

Function specification:

Write a function any_zeroes : int list -> bool that returns true if and only if the input list contains at least one 0

Code:

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

Error:

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

I don't know why Ocaml is having an issue with the 0 when I marked l to be an int list . If anyone could help me fix the issue this would be greatly appreciated!

Thanks!

So, first of all, you didn't mark l as int list , the syntax:

let any_zeroes l: int list

Means that the any_zeroes is a function, that returns an int list . A correct way to annotate it, is the following:

let any_zeroes (l : int list) : bool

Second, the fact, that you mark something doesn't change the semantics of a program. It is a type constraint, that tells the type inference system, that you want this type to be unified to whatever you specified. If a type checker can't do this, it will bail out with an error. And type checker don't need your constraints, they are mostly added for readability. (I think they are also required by the course that you're taking).

Finally, the error points you not to the l (that, as you think, was annotated), but to the 0 . And the message tells you, that List.exists function is accepting a function of type 'a -> bool as the first argument, but you're trying to feed it with 0 that has type int . So, the type system is trying to unify int and 'a list , and there is no such 'a that int = 'a list , so it doesn't type check. So you either need to pass a function, or to use List.mem as was suggested by Anton.

The type annotation let any_zeroes l: int list = ... means the type of any_zeroes l is int list ; this is not what you mean here.

The correct type annotation related to your specification is:

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

In the top level, it feedbacks:

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

Indeed, this expression fails to typecheck because of the type of List.exists :

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

The first argument is a predicate, which 0 is not. A correct implementation is:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM