# Exposing Alias Types, i find it very irritating

**URL:** <https://discourse.elm-lang.org/t/exposing-alias-types-i-find-it-very-irritating/2359>\
**Category:** Request Feedback\
**Created:** [October 30, 2018, 9:42am UTC](https://discourse.elm-lang.org/t/exposing-alias-types-i-find-it-very-irritating/2359 "2018-10-30T09:42:41Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Lucas\_Payr](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/lucas_payr/32/4993_2.png) [@Lucas\_Payr](https://discourse.elm-lang.org/u/Lucas_Payr)\
**Post date:** [October 30, 2018, 9:42am UTC](https://discourse.elm-lang.org/t/exposing-alias-types-i-find-it-very-irritating/2359/1 "2018-10-30T09:42:41Z")

</div>

Lets start with an example:

```
import MyModule exposing (TypeA,TypeB,TypeC(..))

```

One of these types is a type with exposed constructor, one is an opaque type and one is an alias type.  
As you can see the type with exposed constructor is easy to identify, but the opaque type and the alias type are not.

The problem is now that my alias type has a constructor while my opaque type has not. In a bigger project this can get quite annoying.

**Let me show you what i mean:**  
In a package of mine i exedentally used an alias as an opaque type. Even worse: I could chance the definition of the alias type and it was not considered a major chance.  
Here is the commit:

> <https://github.com/Orasund/pixelengine/commit/5db49775ff3f45aa546eb3a763f01fabb1ec1d53>

Yeah, I know. The commit is a mess.  
The change happend in the module Graphics.Abstract, that is used to hide all my opaque types as well as alias types. I learned my lession, now i only have opaque types in the file. _Also note: this is 0.18 code!_

```
module PixelEngine.Graphics.Abstract exposing (..)

type alias ContentElement msg =
    {- { elementSource : ElementSource <- this is the old code -}
    { elementType : ElementType
    , customAttributes : List (Attribute msg)
    , uniqueId : Maybe String
    }

```

There was actually a test file using the ContentElement constructor that broke as a result of this change. And up untill now I should be the only one using this package, so no real code was hurt by this change. But still, i had expacted it to be a major change.

Im not saying that i blame the versioning-system, im just saying that it is very confusing.

**So how could we fix this?**  
we could force alias types to be epxosed with (…). This way at least we know that an element has a useable constructor. Personally i do not like this chance, also because it would not be able to be implemented in 0.19.

i propose to add a new syntax:

```
import MyModule exposing ((TypeA),TypeB,TypeC(..))

```

This syntax could be **optional**. And we could let elm-format help us replace the existing code. When using it, the difference between opaque and alias type would be always clear. This proposal would not break any existing code and could be implemented in 0.19.

If you have another idea how one could make that difference clearer, please, now is your chance. 😉

---

<div class="post-metadata">

**Author:** ![joelq](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/joelq/32/445_2.png) [@joelq](https://discourse.elm-lang.org/u/joelq)\
**Post date:** [October 30, 2018, 2:53pm UTC](https://discourse.elm-lang.org/t/exposing-alias-types-i-find-it-very-irritating/2359/2 "2018-10-30T14:53:51Z")

</div>

> The change happend in the module Graphics.Abstract, that is used to hide all my opaque types as well as alias types.

I think part of your frustration here may be caused by a misunderstanding of type aliases. When you define a type alias, you aren’t creating a new type. Instead, you’re creating an alternate name for an _existing_ type. **This means you can’t really hide a type alias.**

If the underlying type you’re renaming is available outside the module, anyone can construct it or use it in a type signature. They can even give it their own alternate name. All of which are compatible and will type-check with your “hidden” alias. **Hiding type aliases generally provides no type safety benefits**

Of course, if you alias an opaque type then the alias is also effectively opaque. Remember, _an alias is just an alternate name for an existing type_.

---

<div class="post-metadata">

**Author:** ![joelq](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/joelq/32/445_2.png) [@joelq](https://discourse.elm-lang.org/u/joelq)\
**Post date:** [October 30, 2018, 2:56pm UTC](https://discourse.elm-lang.org/t/exposing-alias-types-i-find-it-very-irritating/2359/3 "2018-10-30T14:56:11Z")

</div>

Here’s a concrete example. If you try to define a type alias in a module and then **don’t export it.**

```elm
module User exposing (default)

type alias User = { name : String, age : Int }

bob : User
bob =
  User "Bob" 42 

```

In a _different module_, I can still construct valid users as well as use the underlying type in signatures.

```elm
module OtherModule exposing (..)

alice : { name : String, age : Int }
alice =
  { name = "Alice", age : 39 }

ageDifference : { name : String, age : Int } -> { name : String, age : Int } -> Int
ageDifference user1 user2 =
  abs (user1.age - user2.age)

```

Even though _neither `User` type alias nor the constructor have been exposed_, I can still execute code like

```elm
OtherModule.ageDifference User.bob OtherModule.alice
-- 3

```

---

<div class="post-metadata">

**Author:** ![MarkHamburg](https://avatars.discourse-cdn.com/v4/letter/m/cdc98d/32.png) [@MarkHamburg](https://discourse.elm-lang.org/u/MarkHamburg)\
**Post date:** [October 31, 2018, 2:45pm UTC](https://discourse.elm-lang.org/t/exposing-alias-types-i-find-it-very-irritating/2359/4 "2018-10-31T14:45:46Z")

</div>

That’s true but it also relies on the fact that all record types already exist in the universe and hence we are just giving a name to something that already exists.

Many uses of records, however, don’t feel that way. Creating a product type feels just like creating a sum type except that you have to stick the word `alias` in. This has been confusing to every programmer I’ve watched trying to learn Elm which is a small sample size but the results have been 100% on it being a stumbling block.

So, arguably, what would be useful is not so much changing how type aliases are exported but rather providing a way to create new record types without having to wrap them in custom types which then have to be stripped off and reapplied whenever working with the records. (At least 0.19 now eliminates the memory overhead of wrapping them this way.) The export syntax could even control which fields were publicly revealed if getting ambitious with this.

Mark

(\*) That’s not to say that having something that behaved like an alias inside a module and an opaque type outside a module wouldn’t be useful. It’s just that I suspect records are the most frequent pain point.

---

<div class="post-metadata">

**Author:** ![Lucas\_Payr](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/lucas_payr/32/4993_2.png) [@Lucas\_Payr](https://discourse.elm-lang.org/u/Lucas_Payr)\
**Post date:** [October 31, 2018, 7:48pm UTC](https://discourse.elm-lang.org/t/exposing-alias-types-i-find-it-very-irritating/2359/5 "2018-10-31T19:48:44Z")

</div>

Okey. So what im getting here is, that im currently doing something wrong.  
Let me try to summarize what i understood so far:

1. Alias should be used to increase readability, not to introduce new “types”.But then again, i feel like the model-type is the biggest exception to that rule.
2. if im planning to expose a record, i should always wrap it in a custom type. Is there any exception, for when an exposed alias would be recommanded?

> [@MarkHamburg](#):
>
> So, arguably, what would be useful is not so much changing how type aliases are exported but rather providing a way to create new record types without having to wrap it in custom types which then have to be stripped off and reapplied whenever working with the records.

Yeah… Thats the main reason why i typically do not like to use wrapped records.

---

<div class="post-metadata">

**Author:** ![malaire](https://avatars.discourse-cdn.com/v4/letter/m/b782af/32.png) [@malaire](https://discourse.elm-lang.org/u/malaire)\
**Post date:** [October 31, 2018, 8:17pm UTC](https://discourse.elm-lang.org/t/exposing-alias-types-i-find-it-very-irritating/2359/6 "2018-10-31T20:17:01Z")

</div>

> [@Lucas\_Payr](#):
>
> Alias should be used to increase readability, not to introduce new “types”.But then again, i feel like the model-type is the biggest exception to that rule.

`Model` isn’t an exception. If you have for example `type alias Model = { a: Int }`, then you can use `{ a: Int }` instead of `Model` anywhere in your program. Of course with large `Model` that isn’t practical, which is exactly why type aliases are useful.

---

<div class="post-metadata">

**Author:** ![Lucas\_Payr](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/lucas_payr/32/4993_2.png) [@Lucas\_Payr](https://discourse.elm-lang.org/u/Lucas_Payr)\
**Post date:** [October 31, 2018, 8:23pm UTC](https://discourse.elm-lang.org/t/exposing-alias-types-i-find-it-very-irritating/2359/7 "2018-10-31T20:23:49Z")

</div>

oh no, thats not what i meant!

i wanted to say that if one wants define a type ( := a new thing that will be used a lot) one should not use an alias, but wrap the record in a custom type:

```
type Model = Model {a: Int }

```

but i feel like this would be unnecessary for the model type, as it so much, that a custom type would be really tedious

---

<div class="post-metadata">

**Author:** ![joelq](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/joelq/32/445_2.png) [@joelq](https://discourse.elm-lang.org/u/joelq)\
**Post date:** [October 31, 2018, 8:30pm UTC](https://discourse.elm-lang.org/t/exposing-alias-types-i-find-it-very-irritating/2359/8 "2018-10-31T20:30:54Z")

</div>

> [@Lucas\_Payr](#):
>
> Alias should be used to increase readability, not to introduce new “types”.But then again, i feel like the model-type is the biggest exception to that rule.

It is **impossible** to create a new type using an alias because that’s not what aliases do. The _only_ thing aliases do is allow you to provide an alternate name for an _existing_ type.

Only `type` can create new types, never `type alias`. As mentioned by @MarkHamburg the distinction between the two is often a source of confusion for newcomers to Elm.

> [@Lucas\_Payr](#):
>
> if im planning to expose a record, i should always wrap it in a custom type. Is there any exception, for when an exposed alias would be recommanded?

I often expose type aliases, especially for records that are used in other places outside the current module. I haven’t found that wrapping a custom type around a record to be a useful default thing to do. The bare record type (or an alias to it) is usually perfectly fine to use 🙂

---

<div class="post-metadata">

**Author:** ![system](https://canada1.discourse-cdn.com/flex035/uploads/elm_lang/original/1X/50a05e53677a2c3b47776d7abd0f113eb50193a1.png) [@system](https://discourse.elm-lang.org/u/system)\
**Post date:** [November 12, 2018, 2:08pm UTC](https://discourse.elm-lang.org/t/exposing-alias-types-i-find-it-very-irritating/2359/10 "2018-11-12T14:08:18Z")

</div>

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.
