# What is the difference between a constructor for MyType and a function with output MyType?

**URL:** <https://discourse.haskell.org/t/what-is-the-difference-between-a-constructor-for-mytype-and-a-function-with-output-mytype/2891>\
**Category:** Learn\
**Created:** [August 16, 2021, 10:29pm UTC](https://discourse.haskell.org/t/what-is-the-difference-between-a-constructor-for-mytype-and-a-function-with-output-mytype/2891 "2021-08-16T22:29:28Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Daniel.martchenkov](https://avatars.discourse-cdn.com/v4/letter/d/46a35a/32.png) [@Daniel.martchenkov](https://discourse.haskell.org/u/Daniel.martchenkov)\
**Post date:** [August 16, 2021, 10:29pm UTC](https://discourse.haskell.org/t/what-is-the-difference-between-a-constructor-for-mytype-and-a-function-with-output-mytype/2891/1 "2021-08-16T22:29:29Z")

</div>

If, say, I define `data MyType = Cons1 String | Cons2 String Int`, how is that different from defining `data MyType = Cons1 String` and then defining a function `Cons2 :: String -> Int -> MyType`? I understand that when declaring a constructor, you don’t actually specify what it “does”, but I’m having a hard time understanding the precise difference.

---

<div class="post-metadata">

**Author:** ![f-a](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/f-a/32/2740_2.png) [@f-a](https://discourse.haskell.org/u/f-a)\
**Post date:** [August 16, 2021, 10:59pm UTC](https://discourse.haskell.org/t/what-is-the-difference-between-a-constructor-for-mytype-and-a-function-with-output-mytype/2891/2 "2021-08-16T22:59:10Z")

</div>

Your signature for `cons2` (`String -> Int -> MyType`) suggests that jump from `Cons1` to `Cons2` without losing any info, akin to, say:

```
data Colour = RGB Int Int Int
            | HSL Int Int Int -- Hue, Saturation, Luminosity

```

Is that correct?

In that case I would not use two constructors but just one, having helper functions to output specific representations (`toRGB, toHSL :: Colour -> (Int, Int, Int)`.

Compare with another type like

```
data ChatMessage = IOT
    | Handshake Int
    | DirectMessage String
    | ClientEnquiry Specs
    ⁝

```

where constructors carry different information, not just a different representation of the same data.

---

<div class="post-metadata">

**Author:** ![ntwilson](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/ntwilson/32/863_2.png) [@ntwilson](https://discourse.haskell.org/u/ntwilson)\
**Post date:** [August 17, 2021, 3:58am UTC](https://discourse.haskell.org/t/what-is-the-difference-between-a-constructor-for-mytype-and-a-function-with-output-mytype/2891/3 "2021-08-17T03:58:15Z")

</div>

You’re correct that when you define `data MyType = Cons1 String | Cons2 String Int`, it does indeed create a constructor function that has the signature `Cons2 :: String -> Int -> MyType` (this can be verified in GHCi:

```nohighlight
> data MyType = Cons1 String | Cons2 String Int
> :t Cons2
Cons2 :: String -> Int -> MyType

```

). But in order for `MyType` to behave as a data structure, you have to be able to “get the data back out” that you put into it. `Cons2` as a data constructor has an additional property that a plain `Cons2` function would not, which is that you can _pattern match_ on it. Specifically, you can pattern match on a given `MyType`, and if that `MyType` was a `Cons2`, your pattern can extract both the original `String` and `Int` that you put into it. For example:

```haskell
printMyType :: MyType -> String
printMyType (Cons1 str) = str
printMyType (Cons2 str i) = str ++ show i

```

Now if I say `printMyType (Cons2 "saturn" 5)`, I’ll get back `"saturn5"` because I was able to use both the `String` data and the `Int` data that I put into it. Note that my definition of `printMyType` would _not have compiled_ if `MyType` was setup like so:

```haskell
data MyType = Cons1 String
Cons2 :: String -> Int -> MyType
Cons2 str i = ...

```

If I had used this setup, `printMyType` would only be allowed to have a branch for `Cons1`, and could only ever extract a single `String` value from a `MyType`. `Cons2` wouldn’t be a valid case. Therefore any information about the `Int` that you “constructed” your `MyType` with would necessarily be lost.
