Exposing and importing a data constructor from another module - elm

In my Elm program I want to define a type in one module:
MyModule.elm:
module MyModule exposing (MyType)
type MyType = Constr1 String | Constr2 Int
and construct a value of this type in another module:
Main.elm:
import MyModule exposing (MyType)
import Html exposing (text)
main =
let x = Constr1 "foo" in
text "hello"
When I build this with:
elm-package install elm-lang/html && elm-make Main.elm
I get:
NAMING ERROR ------------------------------------------------------- Main.elm
Cannot find variable `Constr1`
6| let x = Constr1 "foo" in
^^^^^^^
Detected errors in 1 module.
If I use (..) in both exposing clauses, this compiles fine, but I would like to know how to express that I want to expose the constructors.
Side note: I would also like to know where I should have found this in the docs.

You can specify which constructors to expose like this:
module MyModule exposing (MyType(Constr1, Constr2))
All constructors of a type can be exposed using (..) notation:
module MyModule exposing (MyType(..))
And if you don't want to expose any constructors (meaning you have other exposed functions that create values of your type, you specify only the type:
module MyModule exposing (MyType, otherFunctions)
There is community documentation around this topic at elm-community.github.io/elm-faq

Related

How to import theorems from Coq.Numbers.NatInt.NZDiv?

In this doc link there are useful theorems about division. I tried importing it using Require Import in CoqIDE 8.9.0, however while the import succeeds, the following code fails with The reference div_lt_upper_bound was not found in the current environment.
Require Import Coq.Numbers.NatInt.NZDiv.
Check div_lt_upper_bound.
I tried downloading the source code for the file and manually importing it via Load, but then I get the following message with no further explanation (the first line is in red):
Application of a functor with too few arguments.
Interactive Module Type DivMod started
div is declared
modulo is declared
Module Type DivMod is defined
Interactive Module Type DivModNotation started
Module Type DivModNotation is defined
Module Type DivMod' is defined
Interactive Module Type NZDivSpec started
div_mod is declared
mod_bound_pos is declared
Module Type NZDivSpec is defined
Module Type NZDiv is defined
How do I load those theorems properly? Why did the previous methods not work?
The quick answer is that you are looking at the Module Type (see Print NZDivProp.).
The actual usage is simple, e. g.
Require Import Arith.
Check Nat.div_lt_upper_bound.
(*
Nat.div_lt_upper_bound
: forall a b q : nat, b <> 0 -> a < b * q -> a / b < q
*)

Redundant export usage?

Is there any reason to use "export" in a file (which contains no modules) that will be included in another file later on? I came across this type of export usage when looking at some packages on GitHub, which made me wonder. For instance, consider Foo.jl:
# Foo.jl
export foo1
function foo1()
do something
end
function foo2()
do something
end
Which is included in Bar.jl
# Bar.jl
module Bar
include("Foo.jl")
other stuff
end
Won't the function foo2() be in the scope of Bar regardless, thus making the use of "export" totally unnecessary? I saw this type of stuff in several different packages, and don't really get the reason.
Thanks a lot in advance for any help,
Renato
These exports are not redundant. These exports are not about the scope of Bar but rather the scopes of other modules that import Bar. If you import the module Bar via using Bar in another module or in Main, the name foo1 will be public so that you only need to write just foo1 without qualifiers to access the function foo1 instead of Bar.foo1.
If you remove that export statement from Foo.jl you will see that you can no longer access the function foo1 without module name qualification after issuing using Bar. You either have to write Bar.foo1 or explicitly make foo1 visible in that module via, for example, using Bar: foo1 or import Bar: foo1.
The include statement simply makes Julia evaluate the code in that module so you can think of Bar.jl as if it is
# Bar.jl
module Bar
export foo1
function foo1()
do something
end
function foo2()
do something
end
other stuff
end
So the export statement exports the name of foo1 in Bar to the other modules that import the module Bar.
You can find more information about importing, exporting and module system in the Julia documentation.
Within a module, you can control which names from other modules are
visible (via importing), and specify which of your names are intended
to be public (via exporting).
https://docs.julialang.org/en/v1/manual/modules/index.html#modules-1

Can I import just one declaration from an F# module?

Suppose I have a module like this:
module Foo
let x = 1
let y = 2
Now I can use this module like this:
module Bar
let z = Foo.x + Foo.y
Is it possible to import a definition from Foo such that it does not need to be qualified?
Something like:
module Bar
import x from Foo // Not real code
let z = x + Foo.y // x need not be qualified
Note that I do not want to import everything from Foo
You cannot, there is no direct F# equivalent to the ES6 import { ... } from 'Module' syntax. F# supports organizing code into both modules and namespaces, but both modules and namespaces are 'imported' in their entirety with the open keyword. As mentioned in the comments, you can use local bindings to simplify qualified access to values (such as let exchangeRange = Conversions.Currency.UsdToCadExchangeRate) or type aliases to simplify qualified access to types (type Converter = Conversions.Currency.CurrencyConverter).
In addition, modules can be marked with the [<AutoOpen>] attribute to make their contents accessible without qualified access, or the [<RequireQualifiedAccess>] attribute to make their contents accessible only when qualified, even if the module is referenced in an open expression.
See this MSDN article for more information.

import HTML.App as Html

The elm tutorial at http://guide.elm-lang.org/architecture/user_input/buttons.html has these lines:
import Html exposing (Html, button, div, text)
import Html.App as Html
I do not understand what the name Html references as the result of these imports. Is it Html.App or the function from Html package? And why.
import Html exposing (Html)
exposes the identifier Html in two different namespaces.
The Html coming from the brackets part is a type. It's qualified name is Html.Html and it can only appear in Type signatures.
The Html module which can only appear as a qualifier. Hence you could write Html.img and this refers to the part immediately after the import keyword.
Finally,
import Html.App as Html
imports the Html.App module and also gives it a local alias of Html. These don't shadow each other but as long as the actual function names are different in each module the compiler will resolve these correctly for you.
I generally avoid aliasing to the same thing since it makes the code confusing for me. But the compiler deals with it no problem.
Here is my understanding...
if Html is used alone then it refers to a type defined
inside of Html module, and it can be used alone because
it is exposed by import directive.
(i.e. Html.Html)
Html.xx (xx is arbitrary, whichever Html.App module exposes)
is xx exposed by module Html.App (i.e. Html.App.xx).
And it cannot be used alone, because it is not imported with
name spacing with a word Html.
Note that, a period . can only be name-spacing operator if
the left-side word starts with a capital letter.
And, only value (has to starts with a lower-case letter) can have properties, where . can also be used.
(ModuleName.TypeName vs recordValue.property)
So, it is not ambiguous.
But, if two modules expose same name
(e.g. Html.xx and Html.App.xx)
, then xx can become ambiguous
and compiler would complain.
for example, when Html modules is imported with exposing (..)
I hope it makes sense...
TL;DR:
If there is just Html, it's the type (originally Html.Html).
But if there's . after it, it's a module name and you can take definitions from both Html and Html.App modules by doing Html.something.
More in detail:
The result of import Html is that you can access Html.whateverHtmlExposes.
The result of the exposing (Html, button, div, text) is that you can write
Html instead of Html.Html (the type),
button instead of Html.button (function),
etc.
The result of import Html.App would be that you can access Html.App.whateverHtmlAppExposes, BUT because of the as Html part you can now write it like Html.whateverHtmlAppExposes.
Don't worry about conflicts - the compiler will warn you in that case:
-- NAMING ERROR ---------------------------------------------------------- C.elm
This usage of variable `A.x` is ambiguous.
9| Html.text A.x
^^^
Maybe you want one of the following?
A.x
B.x
Detected errors in 1 module.
Here I have imported B as A, both modules have x exposed:
A.elm
module A exposing (x)
x = "x from A"
B.elm
module B exposing (x)
x = "x from B"
C.elm
module C exposing (..)
import A
import B as A
import Html
main = Html.text A.x
import Html.App as App
Its basically importing the application from html package. These functions will help you set up an Elm program that follows the Elm Architecture, a pattern for creating great code that stays great as your project grows.

How to get a module type from an interface?

I would like to have my own implementation of an existing module but to keep a compatible interface with the existing module. I don't have a module type for the existing module, only an interface. So I can't use include Original_module in my interface. Is there a way to get a module type from an interface?
An example could be with the List module from the stdlib. I create a My_list module with exactly the same signature than List. I could copy list.mli to my_list.mli, but it does not seem very nice.
In some cases, you should use
include module type of struct include M end (* I call it OCaml keyword mantra *)
rather than
include module type of M
since the latter drops the equalities of data types with their originals defined in M.
The difference can be observed by ocamlc -i xxx.mli:
include module type of struct include Complex end
has the following type definition:
type t = Complex.t = { re : float; im : float; }
which means t is an alias of the original Complex.t.
On the other hand,
include module type of Complex
has
type t = { re : float; im : float; }
Without the relation with Complex.t, it becomes a different type from Complex.t: you cannot mix code using the original module and your extended version without the include hack. This is not what you want usually.
You can look at RWO : if you want to include the type of a module (like List.mli) in another mli file :
include (module type of List)