referencing a type constructor in ocamldoc - ocaml

I'm getting ocamldoc warnings:
Warning: Element MyModule.VariantName not found
when using {!MyModule.VariantName} in doc comments.
The ocamldoc doc says
In this chapter, we use the word element to refer to any of the following parts of an OCaml source file: a type declaration, a value, a module, an exception, a module type, a type constructor, a record field, a class, a class type, a class method, a class value or a class inheritance clause.
and later when explaining text formatting:
∣ {! string } insert a reference to the element named string. string must be a fully qualified element name, for example Foo.Bar.t. The kind of the referenced element can be forced (useful when various elements have the same qualified name) with the following syntax: {! kind : string } where kind can be module, modtype, class, classtype, val, type, exception, attribute, method or section.
Can I reference a type constructor using {! string }?
How do the first group of kinds of elements relate to the second group of kinds of elements?

After looking at the implementation, it looks like it is possible to refer to a variant constructor, but with a rather weird syntax: you must use the {!typename.constrname} syntax or, from another module, {!Modulename.typename.constrname}. With the code example below, that would by {!mylist.Cons} for example. This will generate a hyperlink, but unfortunately the text will still be typename.constrname and not just refer to the constructor name itself.
(I also learned that there is an "explicit" way to tell ocamldoc to which syntactic category the mentioned identifier belong, I suppose to help in some ambiguous case. So just as you could use either {!mylist} or {!type:mylist} to denote a type constructor, you can use either {!mylist.Nil} or {!const:mylist.Nil} to denote the variant constructor.)
Vocabulary note: In the type declaration
type 'a mylist =
| Nil
| Cons of 'a * 'a mylist
the names Nil and Cons are not called "type constructors", but only "constructors" or "variant constructors". The type constructors are the names of parametrized types (or non-parametrized, for constant type constructors) living at the type rather than the value level, mylist in this example.

Related

Does a constructor has a "type" in C++ since it is a special member function

I recently learnt that constructors do not have names in C++ and some other things about them. I am also aware that a function has a type in C++ called a function type. For example,
void func(int)
{
}
In the above snippet the func has the function type void (int).
Now, I want to know that since constructors are special member functions then do they also have a type like the one shown above. For example say we have:
struct Name
{
Name(int)
{
}
};
Does the constructor shown above also has a function type just like ordinary functions or ordinary member functions. If yes, then how can we find that type. Like we can use decltype on ordinary functions, is it permitted to use decltype on constructors to find their type.
is it permitted to use decltype on constructors to find their type
It's not permitted. Primarily because there is no way to name a constructor. A common misnomer is that an expression like Name(0) or new Name(0), calls the constructor. But that isn't the case like in func(0). A constructor is never called by us directly, but rather always indirectly by the language construct that requires a new object to come into being.
[class.ctor.general]
1 ... Constructors do not have names.
2 A constructor is used to initialize objects of its class type. Because constructors do not have names, they are never found during name lookup; however an explicit type conversion using the functional notation ([expr.type.conv]) will cause a constructor to be called to initialize an object.
[Note 1: The syntax looks like an explicit call of the constructor. — end note]
Because we cannot name them, we cannot use introspection mechanisms like decltype to examine them. Therefore the standard doesn't specify a "type" for constructors, since there is no way for a strictly standard compliant program to examine said type.
A constructor also cannot possess a signature (as defined by the standard), since that by definition includes the function name (and constructors are, as mentioned, nameless).
[defns.signature.member] signature
⟨class member function⟩ name, parameter-type-list, class of which the function is a member, cv-qualifiers (if any), ref-qualifier (if any), and trailing requires-clause (if any)
A classes constructor is never called explicitly. You instantiate an object using something like new Name(5), memory will be allocated and then some part of that memory may be initialized by the steps defined in the constructors body.
Notice that a constructor has no return statement. What is returned by new Name(5) is a memory reference to the memory allocated by new.
This is given away by syntax like:
Name * foo = new Name(5)
foo is the pointer to whatever has be allocated and type checking can be done because Name referrs to a class, not to its constructor.

Why is there no "non-empty list" type in the Haskell base libraries?

This type could be
data NonEmptyList a = NEL a [a]
The functions head, tail, and others will become methods of a newly created Listable type class. Some functions can already fit in an existing type class (maps/folds/traversals/monads).
Why is such a type not part of the Haskell standard library?
It is in base now since GHC 8.0: https://hackage.haskell.org/package/base-4.9.0.0/docs/Data-List-NonEmpty.html
The list of packages that define such a type is itself rather nonempty: there are at least six of them:
NonEmpty
NonEmptyList
Cardinality
non-empty
semigroups
mono-traversable
The Haskell Wiki has a whole page about non-empty lists.
Your question: why are non-empty lists not in the base package is more difficult to answer. But the type is an instance of many useful classes from base (Foldable, Zip) so the machinery for using them is there already, and you need just a small number of instance definitions to use that.
The type actually exists.
You have to import
Data.List.NonEmpty
More info : http://hackage.haskell.org/package/semigroups-0.16.0.1/docs/Data-List-NonEmpty.html
As of GHC 8.0.1, base now has a NonEmpty list type in Data.List.NonEmpty:
https://hackage.haskell.org/package/base-4.9.0.0/docs/Data-List-NonEmpty.html

Defining overloaded constants in Isabelle

How can one define a function in Isabelle that has a different definition depending on either the type of its argument, or the type of the context it is used in?
For example, I might want to define a functions is_default with type 'a ⇒ bool, where each different type 'a has a potentially different "default value". (I am also assuming, for the sake of argument, that existing concepts such as zero are not suitable.)
Isabelle supports overloaded definitions by defining a constant name and then later providing the constant with new definitions for different types. This can be done with the consts command to define the constant name, and then the defs (overloaded) command to provide a partial definition.
For example:
consts is_default :: "'a ⇒ bool"
defs (overloaded) is_default_nat:
"is_default a ≡ ((a::nat) = 0)"
defs (overloaded) is_default_option:
"is_default a ≡ (a = None)"
The above will also work without the (overloaded) parameter, but will cause Isabelle to issue a warning.
The defs command is also given a name, which is the name of the theorem generated by Isabelle which contains the definition. This name can then be used in later proofs:
lemma "¬ is_default (Some 3)"
by (clarsimp simp: is_default_option)
More information is available in section "Constants and definitions" in the Isablle/Isar reference manual. Additionally, there is a paper "Conservative Overloading in Higher-Order Logic" by Obua that discusses some of the implementation details and gotchas in having such a framework without sacrificing soundness.
This kind of overloading looks like a perfect fit for type classes. First you define a type class for your desired function is_default:
class is_default =
fixes is_default :: "'a ⇒ bool"
Then you introduce arbitrary instances. E.g., for Booleans
instantiation bool :: is_default
begin
definition "is_default (b::bool) ⟷ b"
instance ..
end
and lists
instantiation list :: (type) is_default
begin
definition "is_default (xs::'a list) ⟷ xs = []"
instance ..
end

What is the meaning of the ocaml object syntax `object(...)`?

What does the "object(self: something)" means in Ocaml, inheritance?
class tcp_messaging my_address my_cookie (drop_it: drop_function) =
....
object(self : # messaging )
The sharp sign in front of a class name denotes a class type which contains at least the type of the class, so it is more or less an interface denotation.
Ocaml doesn't have a special keyword to reference an object in its implementation (like the keyword this in C++ for instance). Instead, it provides a flexible syntax to define the name which will be used to reference the object instance (in this case the name self is used). It appears that this naming is actually the one used generally (it's kind of a practice), so you will see it very often.
So basically, that syntax let you bind the object to a name, and add a constraint on that name, so that the implementation must implement at least that type. Without the #, the class implementation would need to be exactly of that type.
Incidentally, self binds the value of object itself. Read the following manual.
object(self) defines a value to the current object.
The : #messaging bit says that it implements the interface messaging.

Which style is better to declare a type in Ocaml?

I often need to declare a type which contains a map or a list, for instance:
type my_type_1 = my_type_0 IntMap.t
type my_type_2 = my_type_0 List
Also I have seen another style of declaration which encapsulates map or list in a record, for instance:
type my_type_1 =
| Bot_1
| Nb_1 of my_type_0 IntMap.t
type my_type_2 =
| Bot_2
| Nb_2 of my_type_0 List
My question is, whether there are some cases where the second style is necessary and better than the first style?
Thank you very much!
The two types you give are not equivalent, because of the Bot constructor added in the second case. This means that the two my_type_1 do not have the same semantics. Incidentally, the construction Bot | Foo of 'a is already provided by the standard type 'a option, with constructors Some and None, so the type my_type_1 of your second sample is equivalent to a my_type_1 option in the first one.
Whether to use an option type or your own constructors names is up to you. In general, I would advise to you an option type if the semantics of your type coincides with the option idea of failure, being absent, or being undefined. Given your name Bot, I assume this is probably what you're doing, but defining your own constructor names is also ok and can be clearer in some circumstances. The matter has been discussed in depth in this blog post from ezyang.
Now, assuming your two types definition were equivalent (that is, in absence of the Bot) constructor, what's the purpose of adding an algebraic datatype layer, a new constructor, instead of using a simple type alias ? Well, it has the effect of making your type distinct from the representation type. For example, if you define type 'a stack = Stack of 'a list, 'a stack and 'a list cannot be confused for each other, and the compiler will raise an error if you do. So that can be used to enforce a (light) type separation, with the constructor acting as a type annotation:
let empty = Stack []
let length (Stack li) = List.length li
I'd say it's mostly a matter of taste, but I would recommend using an algebraic datatype instead of an alias when you want to be sure that there can be no mistake with the original type. The downside is that you have to wrap the operations of the original datatype, as I did in my length function above.
Those are not different styles, but different types: the first type declarations are an abbreviation for a specialized instance (for mytype_0) of the polymorphic List, or IntMap.
The second set of definitions present a "constructed" type, for which Bot_1 (and Bot_2) provide values. Those "alternatives" can be used, for example, to create functions of type T -> my_type_1 which return Bot_1 in a special case where the computation doesn't allow to return a list, in a similar way of what an option type permits. This is impossible with the first set of definitions (who must always provide the required list payload).
The second one isn't a "record" (which is a different thing). It creates an algebraic data type. I'm not sure how to explain it but if you've used Haskell or Standard ML you'll know. It's basically a tagged union. A my_type_1 is either a Bot_1 (which carries no data) or a Nb_1 (which carries a my_type_0 IntMap.t as data).
The first one is simply a type synonym (like a typedef in C).