What is the meaning of `Cmd msg`? - elm

I'm trying to use ports to pass an URL to Javascript in order to redirect the user to another page. I wrote a port module to contain all the ports needed for my project :
port module Utils exposing (..)
port changePage : String -> Cmd Event
Then, I imported it in my Elm file :
type Event = PageChange String
import Utils exposing (changePage)
But the compiler didn't like it :
It looks like the keyword `import` is being used as a variable.
8| import Utils exposing (changePage)
^
Rename it to something else.
So I moved the port definition to the main file :
type Event = PageChange String
port changePage : String -> Cmd Event
But the compiler still didn't agree :
Port `changePage` has an invalid type.
28| port changePage : String -> Cmd Event
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
You are saying it should be:
String -> Platform.Cmd.Cmd BmC.Index.Event
But you need to use the particular format described here:
<http://guide.elm-lang.org/interop/javascript.html#ports>
So I went to see that particular format, port check : String -> Cmd msg. I didn't understand where that msg came from, so I went to check the code, and I still don't understand what that line means.
Where does msg come from? What does type Cmd msg = Cmd mean? Thanks in advance.

import statements have to come before any function or type definitions. That's the reason you got a compile error on this code:
type Event = PageChange String
import Utils exposing (changePage)
On your questions of ports: Elm's ports are a feature that are on the edge of the architecture. They allow for interop with a different language, so there is, for all intents and purposes, a little magic going on behind the scenes.
Other languages have similar "magical" constructs for interop with other languages. Haskell has Foreign Function Interface (FFI) and C# has the extern keyword to call external libraries.
The definition of Cmd is one of those pieces that doesn't really make sense by looking at the code.
type Cmd msg = Cmd
That doesn't really tell us much, but that's ok. It's more of a placeholder that the compiler fills in on compile time. Other languages do that too. Haskell often uses a bottom call of let x = x in x to signify a function that the compiler will actually implement.
So, unless you're truly interested in the implementation of that crossover between Elm and Javascript, it's ok it leave it to the imagination and accept the magic.
As for being able to specify a concrete type in your port, that's just another choice of the compiler team. Even though a Cmd Event is the only thing that could go through the port, they chose to force a generic type as the Cmd's type parameter. The exact spelling of Cmd msg isn't required. msg could be anything lowercase:
port check : String -> Cmd a

Port declaration in Elm by design require a very specific type definition annotation.
Firs of all I would recommend looking into Reading Types and especially in the paragraph mentioning type variables
After that, make sure you are familiar with Generic Data Structures and if the official guide doesn't help, you can look into my answer to the similar question Understanding generic union types in Elm
Ports are slightly confusing so I have opened an issue The guide on JavaScript interop should explain port function type definitions
Outgoing port
port out : String -> Cmd msg
| |
| |
Concrete type Generic type
of outgoing with `msg` type variable
data
Outgoing port never sends messages,
but you need to specify the type so the
compiler can infer, that you can use
this command to send the outgoing values
in any module, that imports "out" function
Incoming port
port in : (List String -> msg) -> Sub msg
| |
| |
A function, that accepts Has to be generic,
outgoing data and returns because it is going to be
a message. This function a subscription with the
is called "tagger" same type as "tagger" returns
Has to be generic, i.e. use
`msg` type variable

Your first compiler error is because your import succeeds a definition, but the required format is to have all imports preceding all definitions.
As for what msg in String -> Cmd msg means, it is simply a type variable - all lowercase type names in type annotations in Elm are type variables, while those beginning with an uppercase letter are concrete types. So it's the same as String -> Cmd a or String -> Cmd foo.
In Elm, like in Haskell and some other functional languages, if a type variable is in a type annotation, it is implicitly universally quantified. So we read the above type as
changePage : ∀msg.String → Cmd msg
that is, 'for any type msg, changePage can take a String to a Cmd of msg'.
This means the expression changePage "myPage.html" can be used anywhere in your code where you want a command of some type. This seems to make sense, because it represents the command of 'please send "myPage.html" to anyone subscribed to the changePage port'.

Related

what does the elm signature mean in "Program Never Model Msg"?

I'm just starting on elm and without understanding Haskell and its compiler
I'm trying to grasp what the signature mean in Html.program
func: (a -> String) -> String -- this means expects a function and return a string
main: Program Never Model Msg -- What does this mean?
Program is a type parameterized by three type variables: flags, model, and msg. Never is a type that cannot have any value (see the link for a good explanation of what this means and how it differs from the unit type ()).
Program Never Model Msg therefore is the type of a program that doesn't have any flags (Never), has a model of type Model, and passes messages of type Msg.

Elm Language What do the Multiple Types in a row (without the arrow) in a signature mean?

In the Elm language, I'm having a hard time explaining my question...
In these snippets in elm:
I understand the signature in something like
update : Msg -> Model -> Model
where the parameters / output is separated by arrows, but how do I read / grok things like:
Sub Msg
Program Never Model Msg
In:
main : Program Never Model Msg
main =
program
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
}
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.none
In a type signature, parameter types are separated by ->, with the last type being the return value.
If there are no -> symbols, then it means it is a value of that type. In your main example, the type of main is Program Never Model Msg. It has no arrows, so it takes no parameters.
Now, each parameter and the return value in the type annotation may have several things separated by spaces, as in your main example. The leftmost is the type, followed by type parameters separated by spaces.
Program Never Model Msg
| | | |
| ------|-----
type type parameters
A type parameter is similar to Generics in a language like C#. The equivalent syntax in C# would be:
void Program<Never, Model, Msg>()
C# doesn't directly correlate because it has a different way of constraining generic type parameters, but the general idea holds.
The Elm guide doesn't currently have a great deal of info, but here is the section talking about types.
Sub Msg, List Int, Program Never Model Msg
Sub, List and Program are type constructors. You can think about them as functions that take a type and return another type.
By themselves, Sub, List and Program are not complete type. They are like a puzzle missing a piece. When one adds the missing piece, the puzzle is complete.
I usually read them in my head using the word of as in a List of Ints, a Program of Never, Model and Msg.

Elm recursive type definition

Just taking a peek at elm code and came across the following type definition:
type Cmd msg = Cmd
I just can't seem to understand how this works. Anybody can explain?
That isn't a recursive type definition, it's defining a type Cmd as a union type with one label, Cmd, which contains no extra information. Usually definitions like this are intended to signal that the type represents values that have no individual meaning in elm.
In this case, the type is defined that way because all operations on Cmd are hidden in platform code, so there's no need for users to be able to examine or destructure Cmd values. Cmd needs to expose a type variable in order to preserve the type safety of Cmd values, because they encapsulate a promise to yield a message of a given type and that type can be be changed via Cmd.map .

Difference between dynamic and static type in Dart

Two questions.
First,
Below is strong type.
String msg = "Hello world.";
msg = "Hello world again.";
And, below dynamic
var msg = "Hello world.";
msg = "Hello world again.";
Is there any difference between the two 'msg's above?
Second, if I use 'new' keyword to initiate a variable as below,
Map myMap = new Map;
Why to indicate the variable 'myMap' is a Map instance(Map myMap) as 'new' keyword already include the same meaning? So, isn't it okay just,
myMap = new Map;
Because the 'new' keyword already implies the newly initiated variable is both variable and Map type, I can't understand why normally 'Map' keyword is with the variable name, even 'var' also.
Does anyone have any idea about this (seems a little bit redundant) Dart grammar?
In regard to the first question, there will be no difference in what each msg variable contains.
For the Map question, the reason for specifying the type of a variable that is constructed at declaration is to allow some flexibility with subclasses. Take for example the following code:
class SubMap extends Map {
SubMap() : super();
}
Map map = new SubMap();
Here we have a variable map which contains a SubMap object as its value, however we are allowing it to contain values of type Map (or other types which subclass Map) at later times.
The main thing to remember with Dart is that it is optionally typed. When running your code, none of your type annotiations make any difference at all (unless you run in checked mode). What the type annotations are for is to help your IDE and other tools provide autocomplete help, possible warnings, etc. which other fully dynamic languages like Javascript cannot.
String msg = "Hello world.";
msg = "Hello world again.";
msg = 1; // exception in checked mode - int can not be assigned to String.
var msg = "Hello world.";
msg = "Hello world again.";
msg = 1; // ok in checked mode
Checked mode is the developer mode where type annotations are checked and create runtime exceptions when code violates them.
In unchecked (production) mode it makes no difference if you add a type annotation and which one. This is for performance reasons because checked mode is slower.
The declaration Map myMap = new Map() does three things:
it declares a variable named myMap with type-annotation Map,
it creates a new object using the Map constructor, and
it assigns the object to the variable.
The type annotation means that myMap has static type Map. The static type can give you some warnings at compile time, but it doesn't change anything at runtime.
The type annotation also adds a type check in checked mode, where any assignment to the variable is checked for being assignable to Map.
The object you create could be any object using any constructor. I regularly use new HashMap() instead of new Map(), and still assign it to a variable typed as Map.
Then the object is assigned to the variable, and the type check succeeds, if in checked mode.
The variable is independent of the value used to initialize it. If you later assign a string to the myMap variable, it will fail in checked mode.
So, the difference between the two msg variables is that one has a static type and a type check in checked mode.
For the code you show, there is no difference in behavior.
If the next line was var y = msg + 42;, then the typed version would give a warning (msg has static type String, and String.operator+ has type String->String, so the 42 has an invalid argument type), where the untyped version wouldn't warn you (msg has type dynamic so you probably know what you are doing).

Ocaml unbound module

I'm learning Ocaml language but i have a problem with my modules when i want to compile them.
So, I have a module with the name Door and an other one with the name Case. Into each one, i have a type paramater with the other module :
Door.mli
type t = bool -> Case.u -> t
Case.mli
type u = bool -> Door.t -> u
When i want to compile, i have this error :
File "door.mli", line 14, characters 23-29:
Error: Unbound module Case
Have you got an idea ?
Thanks you
You have two mutually recursive modules, which is always tricky. One way to get them to work is to define them in the same file using module rec A ... and B ....
However, you also have the problem that your types are cyclic. The definition:
type t = bool -> Case.u -> t
is not normally accepted by OCaml either. You can get it to be accepted by specifying -rectypes on the compiler or interpreter command line.
I fear that you'll find these structures to be difficult to work with. The reason they're difficult to define is that they're not usually what you want. You might try starting with more straightforward types if possible.
My advice: get those two types out of door.ml and case.ml, and make Door and Case depend on a common Types module with:
type door = Door of bool -> case -> door
and case = Case of bool -> door -> case