Error (warning 50): ambiguous documentation comment - ocaml

Wrote this code in ocaml (compiling with dune)
(** [insert k v m] is the same map as [m], but with an additional
binding from [k] to [v]. If [k] was already bound in [m], that
binding is replaced by the binding to [v] in the new map. *)
val insert : 'k -> 'v -> ('k, 'v) t -> ('k, 'v) t
when I say dune build it gives error
Error (warning 50): ambiguous documentation comment
What I don't understand is what is ambiguous about this comment? looks pretty clear to me.
I didn't write this code myself I took this from a YouTube tutorial https://youtu.be/hr8SmQK8ld8
Here is my code https://github.com/abhsrivastava/mymaps.git

Neither the code fragment that you have written nor the code that you linked raises the ambiguous documentation comment warning. Thus I can only guess what is the real source of the error.
However, it is important to notice that the [unexpected-docstring] comment is about an ambiguous location of a documentation comment. It is not about the content of the comment.
For instance, removing a line break in your code,
val empty : ('k, 'v) t
(** [insert k v m] is the same map as [m], but with an additional
binding from [k] to [v]. If [k] was already bound in [m], that
binding is replaced by the binding to [v] in the new map. *)
val insert : 'k -> 'v -> ('k, 'v) t -> ('k, 'v) t
yields
Warning 50 [unexpected-docstring]: ambiguous documentation comment
because it is unclear if the documentation comment should be attached to empty or insert.
The general fix for the unexpected-docstring waring is to update the unknown code that raises the warning by adding line breaks between documentation comments and unrelated signature items.

Related

How to use List.fold_left to populate keys of empty string map in ocaml?

I have an existing list, which I would like to move into a empty StringMap. I just want the items in this list to become the keys of said StringMap.
This is what I'm trying to do right now:
utop # List.fold_left StringMap.empty [1,2,3];;
Error: This expression has type 'a StringMap.t
but an expression was expected of type 'b -> 'c -> 'b
But clearly it's wrong as I'm getting the above error message
How should I go about this? Thanks in advance
List.fold_left takes three parameters: a function to be "folded", an initial value, and the list to be processed. You're only supplying two parameters. You need to supply a function that processes each element of the list and produces an intermediate result.
Here is an example that adds up all the elements of a list:
# List.fold_left (fun a b -> a + b) 0 [1;3;5;7];;
- : int = 16
You need a function like the one above except that it should add an element to the map.

ocamldoc not properly displaying parameter names or description with #param

Simply put, let us say I have the following OCaml file called test.ml:
(**
[Test] is a sample module for showing the problem I am having with # tags with OCamlDoc
*)
(**
[id] is the identity function. For any argument [x], [id x] is [x].
#param x The argument, which will be returned
#return The argument [x]
*)
let id (x: 'a): 'a = x
If I run the command ocamldoc -html -all-params -colorize-code test.ml to get the documentation for the Test module, I get the following result:
As can be seen, for the parameter information, it puts () as the name of the parameter and does not include a description for the parameter for some reason.
I am unsure why the parameter name and description are not properly showing up.
If you write let id x = x the display is correct:
The problem is that ocamldoc will not display #param if you provide a tag that doesn't match a named argument but it's not able to extract a named argument from (id : type).
This is a known bug but sadly nobody touched it so... https://github.com/ocaml/ocaml/issues/8804
As ocamldoc's part-time maintainer, there are very few reasons to still use ocamldoc when odoc is available, even more so when writing new documentation.
Ocamldoc's handling of param tag is far too complex for its own good: ocamldoc tries to peek at the definition of the function and only accepts param tag that matches the argument that it can recognize. Here, it fails on explicit type annotation.

OCaml |> operator

Could someone explain what the |> operator does? This code was taken from the reference here:
let m = PairsMap.(empty |> add (0,1) "hello" |> add (1,0) "world")
I can see what it does, but I wouldn't know how to apply the |> operator otherwise.
For that matter, I have no idea what the Module.() syntax is doing either. An explanation on that would be nice too.
Module.(e) is equivalent to let open Module in e. It is a shorthand syntax to introduce things in scope.
The operator |> is defined in module Pervasives as let (|>) x f = f x. (In fact, it is defined as an external primitive, easier to compile. This is unimportant here.) It is the reverse application function, that makes it easier to chain successive calls. Without it, you would need to write
let m = PairsMap.(add (1,0) "world" (add (0,1) "hello" empty))
that requires more parentheses.
The |> operator looks like the | in bash.
The basic idea is that
e |> f = f e
It is a way to write your applications in the order of execution.
As an exemple you could use it (I don't particularly think you should though) to avoid lets:
12 |> fun x -> e
instead of
let x = 12 in e
For the Module.() thing, it is to use a specific function of a given module.
You probably have seen List.map before.
You could of course use open List and then only refer to the function with map. But if you also open Array afterwards, map is now referring to Array.map so you need to use List.map.
The |> operator represents reverse function application. It sounds complicated but it just means you can put the function (and maybe a few extra parameters) after the value you want to apply it to. This lets you build up something that looks like a Unix pipeline:
# let ( |> ) x f = f x;;
val ( |> ) : 'a -> ('a -> 'b) -> 'b = <fun>
# 0.0 |> sin |> exp;;
- : float = 1.
The notation Module.(expr) is used to open the module temporarily for the one expression. In other words, you can use names from the module directly in the expression, without having to prefix the module name.

Why does currying foldr with # produce an operator domain error?

So I'm writing a flatten fn, and I got it to this:
fun flatten ls = List.foldr op # [] ls
And I realized that naming the variable ls should be unnecessary, instead I could probably just paritally apply foldr. But this breaks:
val flatten = List.foldr op # []
Whats making it mess up? I seems like the typ would have to be inferred for both the fun declaration and for the partially applied foldr.
A similar sum function works, which makes me wonder why # is particularly not working:
val sum = List.foldr op + 0
Edit: the error I'm getting:
- val flatten = List.foldr op # [];
stdIn:1.6-2.13 Warning: type vars not generalized because of
value restriction are instantiated to dummy types (X1,X2,...)
val flatten = fn : ?.X1 list list -> ?.X1 list
- flatten [[1], [1]];
stdIn:3.1-3.19 Error: operator and operand don't agree [literal]
operator domain: ?.X1 list list
operand: int list list
in expression:
flatten ((1 :: nil) :: (1 :: nil) :: nil)
I'm a bit unclear on what error exactly you are referring to. You mention in the headline that you are getting an "operator domain error", however you code just produces a "value restriction" warning. There is a big difference.
Value restriction is one of the more complex things to get your head around, but in essence it is there to preserve type safety when having references in the language.
The MLton wiki has a great article on value restriction, which covers Why the value restriction exists, unnecessarily rejected programs, alternatives to the value restriction and how to work with the value restriction.
AJ,
Jesper's article both explains the warning you see, and is insightful, but for a more practical solution to your problem, you might want to try this:
val flatten = foldr op # ([]:int list);
I believe that should solve your problem.
EDIT: I chose int list as the explicit type because I observed the nature of your warning message, and inferred from there, int list was what you needed. [=
Note: Above solution destroys polymorphism and restricts input to the type chosen.

OCaml Error involving lists

I'm still fairly new to OCaml, and would like some assistance on optimizing code.
I'm trying to multiply each element of a given list by the list's last element.
Here's a snippet of my code:
(* Find the last element of a function *)
let rec lastE = function
| [] -> []
| [x] -> x
| _ :: t -> lastE t;;
(*multiply a list by the last element*)
let rec lmul list =
match list with
[] -> []
| hd::tl -> (hd *. (lastE tl)) :: lmul tl;;
When I run the code I get this error message:
Error: This expression has type float list but
an expression was expected of type 'a list list
I'm been studying it for a while, but any assistance on this problem will be much appreciated.
To rephrase differently what Dave Newman is telling you, your basic problem is that lastE needs to handle an empty list differently. If lastE is supposed to return a number, it has to return a number in all cases. As it stands, lastE returns a list when it receives an empty list.
If you don't want to use List.map (again as Dave Newman suggests), you might at least consider calling lastE just once rather than once for each element of the list. This will make a big difference for long lists.