compiler icon indicating copy to clipboard operation
compiler copied to clipboard

Newbies and the evil of import aliases

Open ravensiris opened this issue 4 years ago • 1 comments

The issue

After testing elm for a bit I've encountered this error:

    > elm make src/Main.elm
    Detected problems in 1 module.
    -- TYPE MISMATCH -------------------------------------------------- src/Main.elm
     
    The 2nd argument to `div` is not what I expect:
     
    12|     Html.toUnstyled <| div [] [ svg [] [] ]
                                      ^^^^^^^^^^^^^
    This argument is a list of type:
     
        List (Html.Html msg)
     
    But `div` needs the 2nd argument to be:
     
        List (Html.Html msg)
     
    Hint: I always figure out the argument types from left to right. If an argument
    is acceptable, I assume it is “correct” and move on. So the problem may actually
    be in one of the previous arguments!


Which is very much unreadable. How does List(Html.Html msg) not match List(Html.Html msg) ? Makes no sense just looking at the error alone.

Main.elm code:

    module Main exposing (..)
     
    import Html.Styled as Html exposing (a, div, text)
    import Html.Styled.Attributes as Attr exposing (css)
    import Svg exposing (path, svg)
    import Svg.Attributes as SvgAttr
     
     
    main =
        Html.toUnstyled <| div [] [ svg [] [] ]

The culprit

After fiddling around some more I found the culprit:

 import Html.Styled as Html exposing (a, div, text)

Using as Html to be exact.

Code cleansed of evil import aliases

After testing this:

module Main exposing (..)

import Html.Attributes as Attr
import Html.Styled exposing (a, div, text)
import Svg as Svg exposing (svg)
import Tailwind.Breakpoints as Bp
import Tailwind.Utilities as Tw

main = 

    div
        []
        [ svg [] [] ]

The issue was much more clear, causing this compile error:

The 2nd argument to `div` is not what I expect:

11|     div
12|         []
13|         [ svg [] [] ]
            ^^^^^^^^^^^^^
This argument is a list of type:

    List (Html.Html msg)

But `div` needs the 2nd argument to be:

    List (Html.Styled.Html msg)

Hint: I always figure out the argument types from left to right. If an argument
is acceptable, I assume it is “correct” and move on. So the problem may actually
be in one of the previous arguments!

See how it is now: List (Html.Html msg) and List (Html.Styled.Html msg) ?

My hopes

My suggestion is for the compile errors to expand import aliases(as) whenever left and right side have ambiguous types or do it always. Or oh well it was all my fault for using as improperly.

Some haskell exercises

Below I tried to replicate the issue in haskell. My haskell is pretty bad but hopefully I replicated it well.

Main.hs

import Html (Html, makeHtml)
import HtmlTwo as Html (fromHtml)

main = do
  putStrLn $ show $ (fromHtml . makeHtml) "test"

Html.hs

module Html (Html, makeHtml, fromHtml)
where

newtype Html a = Html a deriving Show

makeHtml :: a -> Html a
makeHtml a = Html a

fromHtml :: Html a -> a
fromHtml (Html a) = a

HtmlTwo.hs

module HtmlTwo (Html, makeHtml, fromHtml)
where
newtype Html a = Html a deriving Show

makeHtml :: a -> Html a
makeHtml a = Html a

fromHtml :: Html a -> a
fromHtml (Html a) = a

Compile error

> ghc -dynamic Main.hs
[3 of 3] Compiling Main             ( Main.hs, Main.o )

Main.hs:6:33: error:
    • Couldn't match type: Html String
                     with: HtmlTwo.Html a0
      Expected: String -> HtmlTwo.Html a0
        Actual: String -> Html String
      NB: ‘HtmlTwo.Html’ is defined in ‘HtmlTwo’
          ‘Html’ is defined in ‘Html’
    • In the second argument of ‘(.)’, namely ‘makeHtml’
      In the expression: fromHtml . makeHtml
      In the second argument of ‘($)’, namely
        ‘(fromHtml . makeHtml) "test"’
  |
6 |   putStrLn $ show $ (fromHtml . makeHtml) "test"
  |                                 ^^^^^^^^

Input

If I didn't butcher the haskell example it should show that haskell properly expands the types with module names ignoring aliases. Also NB: ‘HtmlTwo.Html’ is defined in ‘HtmlTwo’ ‘Html’ is defined in ‘Html’ seems to be really helpful. Hopefully it would be added to the elm compiler in the future, sparing newbies from having cryptic errors as such.

  • Elm: 0.19.1

ravensiris avatar Oct 17 '21 19:10 ravensiris

Thanks for reporting this! To set expectations:

  • Issues are reviewed in batches, so it can take some time to get a response.
  • Ask questions in a community forum. You will get an answer quicker that way!
  • If you experience something similar, open a new issue. We like duplicates.

Finally, please be patient with the core team. They are trying their best with limited resources.

github-actions[bot] avatar Oct 17 '21 19:10 github-actions[bot]