Can I import just one declaration from an F# module? - 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.

Related

using multiple-dispatch for functions when they are defined in different modules (Julia)

I tried to use multiple-dispatch for functions that are defined in different modules in Julia, e.g.:
module A
export f
f(i::Integer) = println(i)
end
module B
export f
f(i::AbstractFloat) = println(i)
end
using .A, .B
f(.1)
But it returns an error
WARNING: both B and A export "f"; uses of it in module Main must be qualified
ERROR: LoadError: UndefVarError: f not defined
I understand that julia tries to avoid name conflicts in different modules. But in my case these f functions can be distinguished by their arguments but it still returns an error. In the docs, Julia offers three ways to solve the problem:
Simply proceed with qualified names like A.f and B.f. This makes the
context clear to the reader of your code, especially if f just happens
to coincide but has different meaning in various packages. For
example, degree has various uses in mathematics, the natural sciences,
and in everyday life, and these meanings should be kept separate.
Use the as keyword above to rename one or both identifiers, eg
julia> using .A: f as f
julia> using .B: f as g
would make B.f available as g. Here, we are assuming that you did not
use using A before, which would have brought f into the namespace.
When the names in question do share a meaning, it is common for one
module to import it from another, or have a lightweight “base” package
with the sole function of defining an interface like this, which can
be used by other packages. It is conventional to have such package
names end in ...Base (which has nothing to do with Julia's Base
module).
For the first two solutions, they can't solve my problem since I really need to display multiple-dispatch and they have to be defined in different modules, and I don't understand the 3rd solution. Could someone help me please?
function f() end
module A
export f
Main.f(i::Integer) = println(i)
end
module B
export f
Main.f(i::AbstractFloat) = println(i)
end
using .A, .B
f(.1)
Basically, make them the same function by defining a "prototype" function outside both of them and specialize that function twice in each submodule. Here because module A and B lives in global scope so I used Main., you should use whatever is housing your sub modules

Private values in OCaml module?

Is is possible to have a let binding (whether a function, value etc.) that is private to its module, and not visible from outside?
Let's say we have A.ml:
let exported = 1
let local = 2
I only want exported to be accessible from other modules. B.ml:
let a = A.exported
let error = A.local (* This should error *)
Similar to what let%private does in Reason.
This is the motivation behind signature and mli files: they allow to hide information to the external world and expose only the relevant part of your API and not implementation details. In your case, it would look like
(* A.ml *)
let exported = 1
let local = 2
and
(* A.mli *)
val exported: int
Then only exported will be visible outside of A.ml.
Yes, that's what module signatures and on the file level the .mli file is for.
Briefly explained, add an A.mli, then put the definitions you want to export into it:
val exported : int
This isn't idiomatic, but for completion's sake:
Since 4.08, when open was extended to accept arbitrary module expressions, it's possible to create private bindings without using module signatures:
open struct
let local = 2
end
Before this you'd have to give the module a name and then open it, which will expose the module with its contents, although it can of course be given a name that suggests it shouldn't be used.
module Internal = struct
let local = 2
end
open Internal

How do I use sets in OCaml?

I want to write a function that, given a non-negative integer n, returns the power set of {1,...,n}. So I want to use the Set.S module as found here. But I can't seem to import it. When I run the following code:
open Set.S
let rec power_set n =
if n = 0 then add empty empty else union (iter (add n s) power_set (n-1)) (power_set (n-1));;
let print_set s = SS.iter print_endline s;;
print_set (power_set 2)
I get the error:
File "countTopologies.ml", line 1, characters 5-10:
Error: Unbound module Set.S
Maybe I just don't have the Set.S module installed on my computer? (I've only done the bare bones needed to install OCaml). If this is the case, how would I get it?
The Set.S is a module type, not a module. You can open only modules. In fact, the module Set contains three elements:
the module type OrderedType that denotes the type of modules that implement ordered types;
the module type S that denotes the type of modules that implement Set data structures;
the functor Make that takes a module of type OrderedType and returns a module of type S.
To get a set module you need to create it using the Set.Make functor. The functor has one parameter - the module for the set elements. In modern OCaml (4.08+) you can create a set module for integers as easy as,
module Ints = Set.Make(Int)
and then you can use like this,
let numbers = Ints.of_list [1;2;3]
assert (Ints.mem 2 numbers)
For older versions of OCaml, which doesn't provide the Int module, or for non-standard (custom) types, you need to define your own module that implements the OrderedType interface, e.g.,
module Int = struct
type t = int
(* use Pervasives compare *)
let compare = compare
end
module Ints = Set.Make(Int)
You can also use non-standard libraries, like Janestreet's Core library, which provide sets out of box. The Core library has an Int module that is already charged with sets, maps, hashtables, so it can be accessed without any functors:
open Core.Std
let nil = Int.Set.empty
Or, in the modern (2018-2019) version of Janestreet Core or Base libraries, you can use polymorphic sets/maps, which require you to specify the module for keys only when a new set or map is created, e.g., like this
open Base (* or Core, or Core_kernel *)
let nil = Set.empty (module Int)
let one = Set.add nil 1
let two = Set.singleton (module Int) 2
You have to Make a set module from the Set functor.
module SI = Set.Make(struct type t = int let compare = compare end)
Then you can have a set of ints:
# let myset = SI.add 3 SI.empty;;
val myset : SI.t = <abstr>
# SI.elements myset;;
- : SI.elt list = [3]

Exposing and importing a data constructor from another module

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

Import module into current scope?

The modules have very long names (they make names of the imported functions three times longer then needed), for example: mapconcat looks Project.Utils.mapconcat is there any way to import this function and use it w/o fully qualifying it by the module name?
You can always do :
var x = Project.Utils.mapconcat;
// now use x in place of mapconcat
PS: you can use the import statement to create an alias for a module
import pu = Project.Utils;
// now:
pu.mapconcat
This is assuming Utils is a module name (and not a class).