# Model a Set with at least one element

**URL:** https://discourse.elm-lang.org/t/model-a-set-with-at-least-one-element/4833
**Category:** Learn
**Created:** [December 13, 2019, 5:49pm UTC](https://discourse.elm-lang.org/t/model-a-set-with-at-least-one-element/4833 "2019-12-13T17:49:17Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![pinver](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/pinver/32/2783_2.png) [@pinver](https://discourse.elm-lang.org/u/pinver)
#### Post date: [December 13, 2019, 5:49pm UTC](https://discourse.elm-lang.org/t/model-a-set-with-at-least-one-element/4833/1 "2019-12-13T17:49:17Z")

</div>

Hi everybody,

That’s may first post in the Elm community!

I’m struggling on the best way to model a Set with at least one element inside.  
The idea is to have a Stored type this a No / Yes Set StorageMedium

Someone can point me towards the goal?  
Thank you,  
Paolo

---

<div class="post-metadata">

### Author: ![nicklayb](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/nicklayb/32/2549_2.png) [@nicklayb](https://discourse.elm-lang.org/u/nicklayb)
#### Post date: [December 13, 2019, 6:43pm UTC](https://discourse.elm-lang.org/t/model-a-set-with-at-least-one-element/4833/2 "2019-12-13T18:43:07Z")

</div>

I might have used one of the following personally. I don’t know if that’s what you wanted

```
module StrictSet exposing (init, empty, toSet, insert, remove, fromSet)
import Set exposing (Set)

type StrictSet comparabble
    = Empty
    | Present (Set comparabble)

init : comparable -> StrictSet comparable
init =
    Present

empty : StrictSet comparable
empty =
    Empty

toSet : StrictSet comparabble -> Set comparabble
toSet set =
    case set of
        Present a ->
            a

        _ ->
            Set.empty

insert : comparable -> StrictSet comparable -> StrictSet comparable
insert item set =
    Present <| Set.insert item (toSet set)

remove : comparable -> StrictSet comparable -> StrictSet comparable
remove item set =
    let
        currentSet =
            Set.remove item <| toSet set
    in
    set
        |> Set.remove item
        |> fromSet

fromSet : Set comparable -> StrictSet comparable
fromSet set =
    if Set.isEmpty set then
        Empty

    else
        Present set

map : (comparable -> b) -> StrictSet comparable -> StrictSet comparable
map function set =
    case set of
        Present s ->
            Present <| function s

        Empty ->
            Empty

```

I would also make sure to hide the StrictSet constructor so other packages cannot call directly Present and Empty

---

<div class="post-metadata">

### Author: ![Atlewee](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/atlewee/32/4603_2.png) [@Atlewee](https://discourse.elm-lang.org/u/Atlewee)
#### Post date: [December 13, 2019, 10:39pm UTC](https://discourse.elm-lang.org/t/model-a-set-with-at-least-one-element/4833/3 "2019-12-13T22:39:10Z")

</div>

I guess you can model it something like this:?

```auto
type alias NotEmptySet a =
  ( a, Set a)

```

And you can expose fuctions to convert it to and from a normal set:

```auto
NotEmptySet.singleton item =
  ( item, Set.empty )

NotEmptySet.toSet (firstOfSet,restSet) =
  Set.insert firstOfSet restOfSet

NotEmptySet.insert item (firstOfSet,restSet) =
  if item == firstOfSet then
    (firstOfSet,restOfSet)
  else
    (firstOfSet, Set.insert item restOfSet)

```

---

<div class="post-metadata">

### Author: ![norpan](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/norpan/32/548_2.png) [@norpan](https://discourse.elm-lang.org/u/norpan)
#### Post date: [December 14, 2019, 3:59pm UTC](https://discourse.elm-lang.org/t/model-a-set-with-at-least-one-element/4833/4 "2019-12-14T15:59:48Z")

</div>

I’d just make a module mirroring the set functions using

```auto
module NonemptySet exposing (NonemptySet, ...)

type NonemptySet a = NonemptySet (Set a)

```

and then implement the logic for each case (what happens when you try to remove the last remaining element etc).

---

<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 14, 2019, 7:24pm UTC](https://discourse.elm-lang.org/t/model-a-set-with-at-least-one-element/4833/5 "2019-12-14T19:24:10Z")

</div>

Others have already given good answers. I was thinking it might also be worthwhile looking at some of the other “non-empty” packages. Searching the package site for “non empty” gives 3 results for List, one for String and one for Array. If you have a look at their APIs and source code it could provide some more detailed inspiration! Particularly any differences they have from the core packages.

---

<div class="post-metadata">

### Author: ![pinver](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/pinver/32/2783_2.png) [@pinver](https://discourse.elm-lang.org/u/pinver)
#### Post date: [December 15, 2019, 10:14am UTC](https://discourse.elm-lang.org/t/model-a-set-with-at-least-one-element/4833/6 "2019-12-15T10:14:06Z")

</div>

Thank you to everyone for the great suggestions!

I’m still learning, but I’m enjoying Elm power in modelling properly the data!  
Coming from procedural languages with less expressive power, that’s delightful …

---

<div class="post-metadata">

### Author: ![berend](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/berend/32/2250_2.png) [@berend](https://discourse.elm-lang.org/u/berend)
#### Post date: [December 15, 2019, 9:10pm UTC](https://discourse.elm-lang.org/t/model-a-set-with-at-least-one-element/4833/7 "2019-12-15T21:10:09Z")

</div>

Use [this package](https://package.elm-lang.org/packages/mgold/elm-nonempty-list/3.0.0/List-Nonempty).

---

<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: [December 25, 2019, 9:10pm UTC](https://discourse.elm-lang.org/t/model-a-set-with-at-least-one-element/4833/8 "2019-12-25T21:10:20Z")

</div>

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