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.
Related
https://ocaml.org/api/Stream.html
val from : (int -> 'a option) -> 'a t
Stream.from f returns a stream built from the function f. To create a new stream element, the function f is called with the current stream count. The user function f must return either Some <value> for a value or None to specify the end of the stream.
Do note that the indices passed to f may not start at 0 in the general case. For example, [< '0; '1; Stream.from f >] would call f the first time with count 2.
There are two things confusing me about this example.
1.
I had no luck googling for meaning of [< ... >] syntax. The closest I found was: https://ocaml.org/manual/lex.html#sss:keywords which just says those character sequences are keywords
[< ... ] seems to be used when printing, but not defining, polymorphic variants: https://ocaml.org/manual/polyvariant.html
If I paste in something like [< '0; '1; >] I get a syntax error.
So it's currently quite baffling to me what this example is purporting to show.
2.
The example says that [< '0; '1; Stream.from f >] would call f the first time with count 2
And I just wonder ... why? how? I can see that 2 follows on from '0 and '1, but how do those values influence starting value of f? (and why are they prefixed with '?)
The deprecated Stream module was built to be used with a camlp{4,5} syntactic extension that added support for the [< ...>]. See https://camlp5.github.io/doc/html/parsers.html for more documentation.
However, if you are not maintaining legacy code, you probably want to avoid the Stream module altogether and use the Seq module instead. In particular, Stream will not be part of the standard library starting with OCaml 5.0 .
So in an exercise I am given a list like ["xyz", True, 42]. The question was if that is a valid expression in Haskell and what the type of that expression is.
A list can only hold homogenous types but the type of "xyz"is [Char], the type of True is Bool and the type of 42 is Num p => p. That is different types so I can't put them into a list.
That's what I thought. But the given answer to that exercise is "Yes, it is a valid expression. Show-instance!."
Why is it a valid expression although the types of the list elements are different and what is meant with show-instance? I'm thinking of something like superclasses from object oriented languages but I thought this is not how Haskell works.
If we are allowed to define some more context, we can make this a valid expression, for instance with:
import Data.String(IsString(fromString))
instance IsString Bool where
fromString [] = False
fromString _ = True
instance Num Bool where
(+) = (||)
(*) = (&&)
abs = id
signum = id
fromInteger 0 = False
fromInteger _ = True
negate = not
(here I used the truthiness of Python to convert from an Integer and String literal)
Then we can write it with the OverloadedStrings pragma:
{-# LANGUAGE OverloadedStrings #-}
the_list = ["xyz", True, 42]
This will then be equivalent to:
Prelude Data.String> ["xyz", True, 42]
[True,True,True]
But note that the list still contains only Bools, we only made Bool an instance of IsString and Num to enable us to convert string literals and number literals to Bools.
A list of heterogeneous types is not possible in Haskell, and since by default a Bool is not a Num, we thus can not parse that expression without adding some extra magic.
An additional note is that it is valid Haskell grammar: syntactically there is nothing wrong, it is only in the next stage of the compiler: type checking, etc. that it will raise errors, since the syntax is nonsensical.
My lecturer gave me a hint to check for Existential types in Haskell.
I produced a working example from the description from the link above:
{-# LANGUAGE ExistentialQuantification #-}
module Main where
data Showable = forall a . Show a => MkShowable a
pack:: Show a => a -> Showable
pack a= MkShowable a
instance Show Showable where
show (MkShowable a) = show a
hlist :: [Showable]
hlist = [pack "xyz", pack True, pack 42]
main :: IO ()
main = do
putStrLn "Heterogenous list 'camouflaged' as Showable:"
print hlist
This works and produces indeed the input from the exercise. The datatype extension for Existential Quantification in the first line is necessary.
My explanation (I might have gotten something wrong though):
I create a new type Showablewith one constructor MkShowable that takes any value a as long as it is in typeclass Show and thus makes a Showable out of it.
The method pack makes a Show a become a Showable by using the constructor MkShowable I described in 1.
Showable is made an instance of Show-typeclass and tells that if a Showable(MkShowable a) is to be shown, simply show a. So we can easily print our Showables.
Furthermore I created a (heterogenous) list hlist of type [Showable]and packed the values from my example into it, using pack. The list is printed in the main function.
This really reminds me of object-oriented programming.
Okay, So I am working on creating a function representation for environments in SML:
type name = string
type 'a fenv = name -> 'a
I'm a little stuck on how to proceed with this. The first thing I need to do is define a value fenvEmpty of type 'a fenv, which represents the empty environment (the environment that does not bind any names). So far, I have this:
val fenvEmpty =
let
fun empty (name) = ???
in
empty
end
I'm not sure if I'm on the right track or anything. What am I supposed to return from the function empty? Putting in 0, null, or NONE won't work.
Later, I also have to write functions that returns data associated with a particular name in the environment (a find function), and a function that binds data to a particular name in the environment ( a bind function), but I'm already stuck on the fenvEmpty part.
I presume the teacher wants you to raise an exception when attempting to look up an unbound value:
type name = string
type 'a fenv = name -> 'a
exception UnboundName of name
fun fenvEmpty name = raise UnboundName name
But I think it will help you more if you first try to use a version of fenv that returns NONE for unbound variables. I believe this because, as opposed to exceptions, there's more type structure to the program that will guide you while writing the implementation (see also below). So, first try to write this implementation where fenv is:
type 'a fenv = name -> 'a option
Now, for the later part of the question, you'll have to define a function for associating a name with a value to an existing environment. This would be that function's type:
val fenvAssoc : 'a fenv -> name -> 'a -> 'a fenv
Notice that the above returns a result of type 'a fenv. But remember what fenv actually is. It's "just" a function:
type 'a fenv = name -> 'a
So, this returned value, a function, needs to somehow "remember" the name and value that have been associated with it. How do functions normally "remember" things they've "seen" in the context where they've been defined?
To look up a name's value, you need a third function, which takes an existing environment and a name and returns the value for that name, if any:
val fenvLookup : 'a fenv -> name -> 'a
Again, remember what the type of 'a fenv is:
type 'a fenv = name -> 'a
I'm emphasizing this because the type of 'a fenv restricts you in the operations you can apply to it. You can basically either: a) create a function or b) apply one.
I have created a td element with a call such as:
let td = Dom_html.createTd doc in
I would now like to set an attribute on this object. I have tried this:
td#setAttribute (Js.string "colspan") (Js.string "4")
But I get the error:
Error: This expression has type Dom_html.tableCellElement Js.t
It has no method setAttribute
Simple dash # is used to access method of OCaml object.
Js_of_ocaml has a special syntax (##) to deal with Javascript object.
see http://ocsigen.org/js_of_ocaml/2.4/manual/library
To set an attribute of a dom element:
td##setAttribute(Js.string "key", Js.string "val")
In you case you should rather use :
td##colSpan <- 4
The double dash ## will translate JavaScript field access.
The previous statement translates to td.colSpan = 4.
The type parameter 'a in 'a Js.t is a phantom type used by the type checker to check JavaScript field access. see http://ocsigen.org/js_of_ocaml/2.4/api/Dom_html.tableCellElement-c in your case.
I'm new to OCaml, I'm trying to understand how you're supposed to get the value from an 'a option. According to the doc at http://ocaml-lib.sourceforge.net/doc/Option.html, there is a get function of type 'a option -> 'a that does what I want. but when I type:
# let z = Some 3;;
val z : int option = Some 3
# get z;;
Error: Unbound value get
# Option.get z;;
Error: Unbound module Option
Why isnt this working?
The traditional way to obtain the value inside any kind of constructor in OCaml is with pattern-matching. Pattern-matching is the part of OCaml that may be most different from what you have already seen in other languages, so I would recommend that you do not just write programs the way you are used to (for instance circumventing the problem with ocaml-lib) but instead try it and see if you like it.
let contents =
match z with
Some c -> c;;
Variable contents is assigned 3, but you get a warning:
Warning 8: this pattern-matching is not exhaustive. Here is an example
of a value that is not matched: None
In the general case, you won't know that the expression you want to look inside is necessarily a Some c. The reason an option type was chosen is usually that sometimes that value can be None. Here the compiler is reminding you that you are not handling one of the possible cases.
You can pattern-match “in depth” and the compiler will still check for exhaustivity. Consider this function that takes an (int option) option:
let f x =
match x with
Some (Some c) -> c
| None -> 0
;;
Here you forgot the case Some (None) and the compiler tells you so:
Warning 8: this pattern-matching is not exhaustive. Here is an example
of a value that is not matched: Some None
The usual way to do this is with pattern matching.
# let x = Some 4;;
val x : int option = Some 4
# match x with
| None -> Printf.printf "saw nothing at all\n"
| Some v -> Printf.printf "saw %d\n" v;;
saw 4
- : unit = ()
You can write your own get function (though you have to decide
what you want to do when the value is None).
You should listen to the above posters advice regarding type safety but also be aware that unsafe function such as Option.get (which is available in batteries btw) are usually suffixed with exn. If you're curious this is how Option.get or Option.get_exn could be implemented then:
let get_exn = function
| Some x -> x
| None -> raise (Invalid_argument "Option.get")