1

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.

akonsu
  • 28,824
  • 33
  • 119
  • 194

4 Answers4

3
import Html exposing (Html)

exposes the identifier Html in two different namespaces.

  1. 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.
  2. 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.

Jakub Hampl
  • 39,863
  • 10
  • 77
  • 106
2

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...

Tosh
  • 35,955
  • 11
  • 65
  • 55
1

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
Martin Janiczek
  • 2,996
  • 3
  • 24
  • 32
0

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.

Thennarasan
  • 698
  • 6
  • 11
  • Thanks, but I am confused... There is no such import. The import there gives the `Html.App` name `Html`. – akonsu Jul 21 '16 at 05:28
  • Its the elm package. I think if you go through this, you will get a better understanding. [link](http://package.elm-lang.org/packages/elm-lang/html/1.1.0/Html-App) and for sample implementation refer this[link](https://www.dailydrip.com/topics/elm/drips/our-first-html-application) – Thennarasan Jul 21 '16 at 05:38
  • Well, I am asking this: the two imports in my question above seem to introduce the same name in to the program, and I do not understand how this is possible. The first line in your answer gives an import that is not the same as in the question. That is why I do not understand your answer either... – akonsu Jul 21 '16 at 05:47
  • `import Html exposing (Html, button, div, text)` - To start off just producing some HTML. To do this, we'll import the Html module to start: `import Html exposing (..)` This says we'd like to import everything from the Html module, which is provided by the html package we installed. – Thennarasan Jul 21 '16 at 05:56
  • In you case you are specifying what need to be imported from the pacakge. Assuming you have everything in place and you use `beginnerProgram` - provided by elm It is an easy way of wiring a model, update, and view together to make an application. It came in the html package. We'll import it into our application: `import Html.App as App`.Finally, we'll define our main function using the beginnerProgram function exposed by Html.App – Thennarasan Jul 21 '16 at 05:56
  • Thank you very much, I am perhaps too slow, but, again, there is no import `import Html.App as App` in the code. – akonsu Jul 21 '16 at 05:59
  • You can give any for eg as you code `import Html.App as Html` main function using the beginnerProgram function exposed by Html.App: will look as below `main = Html.beginnerProgram { model = 0 , view = view , update = update }` The name can be anything, what you specify will become the prefix. Now if you updated as `import Html.App as abc` main function will look like ``main = abc.beginnerProgram { model = 0 , view = view , update = update }`` – Thennarasan Jul 21 '16 at 06:04
  • ok, so now we have established that we import `Html.App` and give it an alias `Html`. At the same time the line above that imports a few names from the `Html` module, and one of these names is the `Html` type that is defined in this module. My question was about this fact that we import two different entities and give them the same name. I tried actually, to run this sample, and it seems that the alias for `Html.App` overwrites the type `Html` imported from the `Html` module. Thanks. – akonsu Jul 21 '16 at 06:48
  • @akonsu The alias for Html.App doesn't overwrite the type Html - they live in two separate collections. If you do `view : Html msg`, it still works. – Martin Janiczek Jul 21 '16 at 11:41