# Questions about Custom Types

**URL:** <https://discourse.elm-lang.org/t/questions-about-custom-types/2852>\
**Category:** Learn\
**Created:** [December 30, 2018, 5:12pm UTC](https://discourse.elm-lang.org/t/questions-about-custom-types/2852 "2018-12-30T17:12:33Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Aquazi](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/aquazi/32/1678_2.png) [@Aquazi](https://discourse.elm-lang.org/u/Aquazi)\
**Post date:** [December 30, 2018, 5:12pm UTC](https://discourse.elm-lang.org/t/questions-about-custom-types/2852/1 "2018-12-30T17:12:33Z")

</div>

As I’m reading through the docs and source code I’m often confused by some more “advanced” topics that probably stem from my poor understanding of type annotations and functional programming in general.

One such example is this:

```
type Foo bar = Foo

```

I don’t really understand the role of “bar” here and how to treat it.

Real world examples of that, from the docs:

```
type Maybe a = Nothing | Just a

```

or from the core module Sub:

```
type Cmd msg = Cmd

```

What is that supposed to mean? I am defining a type Cmd which is equal to itself? And what’s the role of msg?

Another example of code I don’t really understand (taken again from the docs):

```
type Msg = GotText (Result Http.Error String)

```

I am having problems reading this kind of code.

I’m defining a type Msg which can be GotText (okay, fair enough) but what’s that tuple after?

I am sorry if I duplicated a question, I tried googling and searching here on discourse but have had no luck.

---

<div class="post-metadata">

**Author:** ![Brian\_Carroll](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/brian_carroll/32/444_2.png) [@Brian\_Carroll](https://discourse.elm-lang.org/u/Brian_Carroll)\
**Post date:** [December 30, 2018, 5:35pm UTC](https://discourse.elm-lang.org/t/questions-about-custom-types/2852/2 "2018-12-30T17:35:06Z")

</div>

So I think this is 3 different examples of 3 different things.

> [@Aquazi](#):
>
> type Foo bar = Foo

This is a “phantom type” and it’s an advanced trick to make sure you can only combine functions together in certain ways. If you’re still learning about Elm types I’d leave this till later. Here’s an article about them anyway:

> **[Advanced Types in Elm - Phantom Types](https://ckoster22.medium.com/advanced-types-in-elm-phantom-types-808044c5946d)**
>
> Part IV: Phantom Types

> [@Aquazi](#):
>
> type Cmd msg = Cmd

This is not something you could ever define in your own code, that’s why it seems so weird. `Cmd` is special because it’s implementation is part of the Elm runtime and is implemented in JavaScript not in Elm. You will never be able to use this in pure Elm code so it’s not necessarily something you need to dig deep into. It’s basically saying “kernel magic here”.

> [@Aquazi](#):
>
> type Msg = GotText (Result Http.Error String)

There are two layers of “wrappers” here, which is what makes it tricky.  
`Result Http.Error String` is the result of a calculation that can succeed or fail. It can be either a String wrapped in an `Ok` constructor or an `Http.Error` wrapped in an `Err` constructor. See here:  
[https://package.elm-lang.org/packages/elm/core/latest/Result](https://package.elm-lang.org/packages/elm/core/latest/Result)

Then `GotMsg` is a wrapper around that (successful or error) value. In your example there’s only one constructor in the `Msg` type so it might seem pointless to have a wrapper at all. But in a real app you’d have lots of `Msg` constructors for all the different things that could happen in the app. This particular one can contain either successful data or error data.

---

<div class="post-metadata">

**Author:** ![Jess\_Bromley](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/jess_bromley/32/3396_2.png) [@Jess\_Bromley](https://discourse.elm-lang.org/u/Jess_Bromley)\
**Post date:** [December 30, 2018, 9:29pm UTC](https://discourse.elm-lang.org/t/questions-about-custom-types/2852/3 "2018-12-30T21:29:17Z")

</div>

@Brian_Carroll’s answer is great. Just to address the one other example you lifted from the docs…

> [@Aquazi](#):
>
> Real world examples of that, from the docs:
> 
> ```auto
> type Maybe a = Nothing | Just a
> 
> ```

This is a _type variable_ as discussed in the guide [here](https://guide.elm-lang.org/types/reading_types.html). It’s describing the fact that you can have a `Maybe` of any other kind of type, e.g. a `Maybe Int` which would have the value of either `Nothing` of `Just <some Int value>`, or a `Maybe String` which would have the value of either `Nothing` or `Just <some String>`.

---

<div class="post-metadata">

**Author:** ![Aquazi](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/aquazi/32/1678_2.png) [@Aquazi](https://discourse.elm-lang.org/u/Aquazi)\
**Post date:** [January 2, 2019, 3:28pm UTC](https://discourse.elm-lang.org/t/questions-about-custom-types/2852/4 "2019-01-02T15:28:38Z")

</div>

Thank you for your answers.

I have still problem reading this kind of syntax tho but I guess this is personal.

How would I know by reading this that GotText is a type of type Result containing either an Http.Error or a String? If I had GotText (A B C D), would it mean I have a type GotText which is a type A containing B C or D as payloads? Would that be correct if A was defined like so?

```
type A b c d = 
  B b |
  C c |
  D d

```

?

So I can later do matching based on B C D values b c d?

---

<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:** [January 2, 2019, 4:08pm UTC](https://discourse.elm-lang.org/t/questions-about-custom-types/2852/5 "2019-01-02T16:08:51Z")

</div>

When you define `type Msg = GotText (Result Http.Error String)` there’s a few things going on. Let’s look at things from the inside-out.

## Result

The [result type](https://package.elm-lang.org/packages/elm/core/latest/Result#Result) is defined as:

```elm
type Result error success
  = Err error
  | Ok success

```

It’s using two [type variables](https://guide.elm-lang.org/types/reading_types.html#type-variables), allowing you to specify what kind of values will be in the `Err` and `Ok` wrappers.

I find it helpful to read the pipe `|` as _OR_. 🙂

So the type `Result Http.Error String` means “a value that is either `Err` wrapping an HTTP error or an `Ok` wrapping a string”. Some concrete examples would be:

- `Ok "hello"`
- `Err NetworkError`
- `Err (BadStatus 404)`

_Check out the [`Http.Error`](https://package.elm-lang.org/packages/elm/http/latest/Http#Error) docs for more details on what might show up inside the `Err` here_

## Msg

You’ve defined your `Msg` type to look like:

```elm
type Msg = GotText (Result Http.Error String)

```

That is to say, all `Msg` values are one of the result values discussed above, wrapped in `GotText`.

Some concrete examples would be:

- `GotText (Ok "hello")`
- `GotText (Err NetworkError)`
- `GotText (Err (BadStatus 404))`

## Your further question on type variables

> [@Aquazi](#):
>
> How would I know by reading this that GotText is a type of type Result containing either an Http.Error or a String?

If you’ve never encountered `Result` before, you can’t know that just from reading `Result Http.Error String`. You can see that the `Result` type takes two parameters but you can’t know that the value will be one _or_ the other (as opposed to one _and_ the other) without looking at the definition in the docs.

In practice since `Result` is part of the core library and is heavily used in Elm code, most people just memorize that it means you’ll get one or the other of the type parameters wrapped in `Err` or `Ok` respectively 🙂

> [@Aquazi](#):
>
> If I had GotText (A B C D), would it mean I have a type GotText which is a type A containing B C or D as payloads? Would that be correct if A was defined like so?
> 
> ```auto
> type A b c d = 
> B b |
> C c |
> D d
> 
> ```

Yes. Using your type above and some more concrete types for the parameters, `A String Bool Int` would mean “either `B` wrapping a string or `C` wrapping a bool or `D` wrapping an integer”. One of the benefits of a type like this is the ability to pattern-match on the different branches.

---

<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:** [January 12, 2019, 4:08pm UTC](https://discourse.elm-lang.org/t/questions-about-custom-types/2852/6 "2019-01-12T16:08:54Z")

</div>

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