{
  "$type": "site.standard.document",
  "bskyPostRef": {
    "cid": "bafyreibk4tehqgjavgqn7be2he5f6srjttl2otjougd7tpdriaevz652gi",
    "uri": "at://did:plc:pi6woz4d47bkuws673w2il2r/app.bsky.feed.post/3mjbgzmni4do2"
  },
  "path": "/t/ann-rivulet-window-manager/13921#post_2",
  "publishedAt": "2026-04-11T23:02:10.000Z",
  "site": "https://discourse.haskell.org",
  "textContent": "A friend of mine offered this funny example of what’s possible with the Rivulet config:\n\n\n    -- ConfigM is a monad but you refuse to use (>>=) on principle\n\n    myConfig :: ConfigM ()\n    myConfig =\n        gaps        <$> pure 4\n                    <*  borders 2 (0xFF000000, 0xFF0000FF)\n                    <*  layout Tall\n                    <*  (keybinds $\n                            bind <$> pure [Super]\n                                 <*> pure q\n                                 <*> pure closeFocused)\n\n\nSo I got to thinking and it would be pretty funny to explore some esoteric uses of the config being just Haskell. For example,\n\n\n    realGaps :: Int\n    realGaps = unsafePerformIO $ do\n        t <- getCurrentTime\n        -- gaps are 4 most of the time but on Tuesdays they are 5\n        let day = dayOfWeek (utctDay t)\n        pure $ if day == Tuesday then 5 else 4\n\n    gaps realGaps\n\n\nor keybindings as a Markov chain:\n\n\n    -- keybindings probabilistically select the next action\n    import System.Random (randomRIO)\n\n    markov :: Action\n    markov = do\n        n <- liftIO $ randomRIO (0 :: Int, 2)\n        [focusNext, focusPrev, closeFocused] !! n\n\n\nThere is likely some really funny things you could do with this DSL. I wonder what other silly things one could come up with, like making your entire config a `Foldable` instance or something.",
  "title": "[ANN] Rivulet Window Manager"
}