# Can I pattern match without a case expression?

**URL:** <https://discourse.elm-lang.org/t/can-i-pattern-match-without-a-case-expression/8500>\
**Category:** Learn\
**Created:** [July 9, 2022, 9:31pm UTC](https://discourse.elm-lang.org/t/can-i-pattern-match-without-a-case-expression/8500 "2022-07-09T21:31:16Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Hubro](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/hubro/32/4630_2.png) [@Hubro](https://discourse.elm-lang.org/u/Hubro)\
**Post date:** [July 9, 2022, 9:31pm UTC](https://discourse.elm-lang.org/t/can-i-pattern-match-without-a-case-expression/8500/1 "2022-07-09T21:31:16Z")

</div>

I’m drawing my sidebar links like this:

```elm
[ viewSidebarLink "/" "Dashboard" "fa-house" (model.page == Dashboard)
, viewSidebarLink "/my-forms" "My Forms" "fa-list" (model.page == MyForms)
, viewSidebarLink "/settings" "Settings" "fa-gear" (model.page == Settings)
]

-- ...

viewSidebarLink : String -> String -> String -> Bool -> Html.Html Msg
viewSidebarLink linkTarget linkText icon active =
    ...

```

This works as long as none of my pages take any extra data:

```elm
type Page
    = Dashboard
    | MyForms
    | Settings
    | Error404

```

However, I want to flesh out my pages, adding extra state for the dashboard, for example:

```elm
type Page
    = Dashboard DashboardState
    | MyForms
    | Settings
    | Error404

```

Now the code for drawing my sidebar links breaks, because I can no longer do `(model.page == Dashboard)`, instead I have to do this awful, ugly, verbose monstrosity:

```elm
[ viewSidebarLink "/"
    "Dashboard"
    "fa-house"
    (case model.page of
        Dashboard _ ->
            True

        _ ->
            False
    )
, viewSidebarLink "/my-forms" "My Forms" "fa-list" (model.page == MyForms)
, viewSidebarLink "/settings" "Settings" "fa-gear" (model.page == Settings)
]

```

Does Elm have any way to check if an expression matches a pattern without doing a full blown case expression?

It seems extremely verbose to use a case expression for this use case, it seems like there should be a shortcut for this, such as `(case model.page of Dashboard _)`.

Or am I using a bad pattern here, is there a better way to achieve the same result? (i.e. check which “branch” of the state I’m in, ignoring any data underneath)

---

<div class="post-metadata">

**Author:** ![dta](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/dta/32/1917_2.png) [@dta](https://discourse.elm-lang.org/u/dta)\
**Post date:** [July 9, 2022, 11:04pm UTC](https://discourse.elm-lang.org/t/can-i-pattern-match-without-a-case-expression/8500/2 "2022-07-09T23:04:58Z")

</div>

No, there is no way to do a non-verbose partial match on an expression in Elm (except for using equality as you have demonstrated). For this situation, I might introduce a new type to model the active state, for example:

```elm
let
  activeDefaults =
    { dashboard = False
    , myForms = False
    , settings = False
    }
  active =
    case model.page of
      Dashboard _ ->
        { activeDefaults | dashboard = True }
      MyForms ->
        { activeDefaults | myForms = True }
      Settings ->
        { activeDefaults | settings = True }
in
[ viewSidebarLink "/" "Dashboard" "fa-house" active.dashboard
, viewSidebarLink "/my-forms" "My Forms" "fa-list" active.myForms
, viewSidebarLink "/settings" "Settings" "fa-gear" active.settings
]

```

---

<div class="post-metadata">

**Author:** ![sdeframond](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/sdeframond/32/4070_2.png) [@sdeframond](https://discourse.elm-lang.org/u/sdeframond)\
**Post date:** [July 11, 2022, 8:10am UTC](https://discourse.elm-lang.org/t/can-i-pattern-match-without-a-case-expression/8500/3 "2022-07-11T08:10:19Z")

</div>

What about testing equality on the URL path ? For example:

```auto
-- This might be useful somewhere else
pageToPath page =
 case page of
    Dashboard _ ->
      "/"
    MyForms ->
      "/my-forms"

viewSidebarLinks model =
  [ viewSidebarLink "/" "Dashboard" "fa-house" ("/" == pageToPath model.page)
  -- ...
  ]

```

---

<div class="post-metadata">

**Author:** ![passiomatic](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/passiomatic/32/1250_2.png) [@passiomatic](https://discourse.elm-lang.org/u/passiomatic)\
**Post date:** [July 11, 2022, 9:06am UTC](https://discourse.elm-lang.org/t/can-i-pattern-match-without-a-case-expression/8500/4 "2022-07-11T09:06:47Z")

</div>

Another unsurprising solution is to just write helper functions like this one:

```elm
isDashboard page = 
    case page of
        Dashboard _ ->
            True

        _ ->
            False

```

Given that you might need those anyway somewhere else in the application. 🙂

---

<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:** [July 21, 2022, 9:07am UTC](https://discourse.elm-lang.org/t/can-i-pattern-match-without-a-case-expression/8500/5 "2022-07-21T09:07:16Z")

</div>

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