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.
src/ contains the definitions for the functions.
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.
src/ contains the definitions for the functions.
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):
BangPatterns pragma to make the data declarations strict, using StrictData pragma does exactly that
show (MkView a b) = a ++ " " ++ show b)rSnap a = MkPos "snap" a, whereas rSnap = MkPos "snap" means the same thing and (I would argue) is just as readable, if not more.rSnap is a synonym for MkPos "snap". It’s called “Eta conversion” if you want to look it up. (but you don’t have to)rSetRepeat = MkTri "set-repeat"
-- which means the same as:
rSetRepeat a b = MkTri "set-repeat" a b
Data.Text's Text type is “always” more performant than Strings.-- if the list only has one element, then
concatMap words [show $ rBackgroundColour a]
-- and
words (show $ rBackgroundColour a)
-- are identical
applyKeybinds a = let x = a in for_ x callRiver
-- and
applyKeybinds a = for_ a callRiver
-- and
applyKeybinds = traverse_ callRiver
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)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 
It seems to have completely missed my mind to make my code pointfree!
and thanks for telling me about StrictData, it’s very nice.
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).
was actually looking for a nicer way to do this, I love it, thank you! ![]()