# riverWM configured with Haskell

**URL:** <https://discourse.haskell.org/t/riverwm-configured-with-haskell/10002>\
**Category:** Show and Tell\
**Created:** [July 22, 2024, 6:40pm UTC](https://discourse.haskell.org/t/riverwm-configured-with-haskell/10002 "2024-07-22T18:40:36Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Hikari](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/hikari/32/4501_2.png) [@Hikari](https://discourse.haskell.org/u/Hikari)\
**Post date:** [July 22, 2024, 6:40pm UTC](https://discourse.haskell.org/t/riverwm-configured-with-haskell/10002/1 "2024-07-22T18:40:36Z")

</div>

I spent the past week or so writing my first actual Haskell program, which is a wrapper over `riverctl` allowing you to configure riverWM in Haskell! I’d love to see what y’all think about it.

> **[river-hs](https://codeberg.org/Hikari/river-hs)**
>
> A riverWM configuration written in Haskell!

src/ contains the definitions for the functions.

---

<div class="post-metadata">

**Author:** ![Vlix](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/vlix/32/1551_2.png) [@Vlix](https://discourse.haskell.org/u/Vlix)\
**Post date:** [July 22, 2024, 10:25pm UTC](https://discourse.haskell.org/t/riverwm-configured-with-haskell/10002/3 "2024-07-22T22:25:30Z")

</div>

Well, first of all, it’s always great to see someone complete their first Haskell program 😃 Way to go 🎉

As to what I think, is that looks pretty good. I didn’t see anything that made me think “Oh this is definitely wrong”, so that’s already a win 👍

A few things that I did notice (and again, read these more as a combination of _general best practice_, but most are probably also just my _personal preference_):

- If you’re using `BangPatterns` pragma to make the data declarations strict, using `StrictData` pragma does exactly that 😉
- I always prefer less parentheses (e.g. `show (MkView a b) = a ++ " " ++ show b`)
- There’s a bunch of argument repetition in definitions like `rSnap a = MkPos "snap" a`, whereas `rSnap = MkPos "snap"` means the same thing and (I would argue) is just as readable, if not more.  
I read it as "`rSnap` is a synonym for `MkPos "snap"`. It’s called “[Eta conversion](https://wiki.haskell.org/Eta_conversion)” if you want to look it up. (but you don’t have to)  
Also compare the following:

```haskell
rSetRepeat = MkTri "set-repeat"
-- which means the same as:
rSetRepeat a b = MkTri "set-repeat" a b

```

- In general, `Data.Text`'s `Text` type is “always” more performant than `String`s.
- The following are identical:

```haskell
-- if the list only has one element, then
concatMap words [show $ rBackgroundColour a]
-- and
words (show $ rBackgroundColour a)
-- are identical

```

```haskell
applyKeybinds a = let x = a in for_ x callRiver
-- and
applyKeybinds a = for_ a callRiver
-- and
applyKeybinds = traverse_ callRiver

```

```haskell
map (unwords . words) (join [[show $ function a], [show $ mode a], [show $ modifier a], [key a], z])
-- and
[show $ function a, show $ mode a, show $ modifier a, key a] ++ z

```

- `riverMapPointer` uses `error`, which is often a sign that the that the type model could be improved. (this is not a strict rule, sometimes it’s just necessary, or way too much of a hassle to change the API)  
In this case, I’d simply return `Either String [String]`, so that `Left` is the error, and `Right` is the successful result. It makes it immediately obvious to a person reading the type signature this might fail and that they can handle it, instead of just crashing the program of anyone using it.

* * *

Good luck on your Haskell journey!  
I hope you’ll have a great time learning more of this wonderful language 😁

---

<div class="post-metadata">

**Author:** ![Hikari](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/hikari/32/4501_2.png) [@Hikari](https://discourse.haskell.org/u/Hikari)\
**Post date:** [July 23, 2024, 8:19am UTC](https://discourse.haskell.org/t/riverwm-configured-with-haskell/10002/4 "2024-07-23T08:19:30Z")

</div>

It seems to have completely missed my mind to make my code pointfree!  
and thanks for telling me about StrictData, it’s very nice.

> [@Vlix](#):
>
> in general, `Data.Text`’s `Text` type is “always” more performant than `String`s.

I did try to use `Text` but, System.Process wants a String so I’d end up converting back and forth between them (which may or may not be slower).

> [@Vlix](#):
>
> `[show $ function a, show $ mode a, show $ modifier a, key a] ++ z`

was actually looking for a nicer way to do this, I love it, thank you! ❤
