I’m excited to introduce Concoct, a new declarative user-interface framework for Haskell.
counter :: (MonadView IO m) => m ()
counter = do
count <- useState $ pure (0 :: Int)
useEffect (readStateRef count) $ \c -> do
putStrLn $ "Count: " ++ show c
writeStateRef count $ c + 1
switchView
(even <$> readStateRef count)
(liftView $ putStrLn "Even!")
(liftView $ putStrLn "Odd!")
useOnUnmount $ do
c <- readStateRef count
putStrLn $ "Unmount:" ++ show c
I’ve been playing around with how to do proper declarative UI for awhile now, first in Rust and then Haskell. I finally feel like I found an interesting pattern that works similarly to ReactJS but with type-safety for hooks and other things that get tricky in React.
By running the main MonadView in multiple passes, similar to how Reflex handles FRP, the actual structure of the UI can be guaranteed to be the same across renders, so it’s impossible to improperly use hooks. More info on the Hackage docs
This feels like a fundamental building block for something bigger, but I cannot really place it. It has no UI dependencies (vty, gtk, qt, …), how is it intended to be used?
I might’ve published it a little too early it should be possible to wire up rendering but I’m hoping to use this as a frontend for the aztecs game engine soon
I like hooks! But I agree in React they can be pretty rough. I’m hoping concoct’s type-safety can eliminate a lot of the annoyance with hooks, and even make them more interesting by having everything essentially be a hook (no major difference from a component and hook) let Android’s Jetpack Compose does. Basically since hooks are guaranteed to run in order, you don’t have to manually enforce hook rules like React, and so they can actually be the primitive for all reactivity