Introducing Concoct - A declarative UI framework

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

14 Likes

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?

6 Likes

I think hooks are the worst thing the react team ever introduced. It makes it so hard to understand the effects of your code. Why introduce them here?