The
Hyperbole effect is automatically available in both, and gives us direct access to the client connection. We can use it to get information about the
request, update the page directly, and more. Here is how you might use it to set the page title.
data Titler = Titler
deriving (Generic, ViewId)
instance HyperView Titler es where
data Action Titler
= SetTitle Text
deriving (Generic, ViewAction)
update (SetTitle msg) = do
pageTitle msg
pure "Check the title"
The following
HyperView uses a
Reader to get a message set at the application level. It also uses
Concurrent to delay the response by 500ms:
{-# LANGUAGE UndecidableInstances #-}
page :: (Hyperbole :> es, Concurrent :> es, Reader Text :> es) => Page es '[SlowReader]
page = do
pure $ hyper SlowReader $ messageView "..."
data SlowReader = SlowReader
deriving (Generic, ViewId)
instance (Concurrent :> es, Reader Text :> es) => HyperView SlowReader es where
data Action SlowReader
= GetMessage
deriving (Generic, ViewAction)
update GetMessage = do
threadDelay 500000
msg <- ask
pure $ messageView msg
Then make sure to add the effect when you run your application or page
app :: Application
app = do
liveApp quickStartDocument $ do
runConcurrent . runReader @Text "Secret!" $
runPage page
Databases and Custom Effects
We can access a database using the IOE effect, but it is better to describe the high-level operations available to the application as a custom effect:
data Todos :: Effect where
LoadAll :: Todos m [Todo]
Save :: Todo -> Todos m ()
Remove :: TodoId -> Todos m ()
Create :: Text -> Todos m TodoId
To use it we need a
run function which converts the abstract operations into a specific implementation. We could implement the Todos
Effect using
Hyperbole Sessions.
main :: IO ()
main = do
run 3000 $ do
liveApp quickStartDocument (runTodosSession $ runPage simplePage)
Alternatively, we could implement the effect using a database instead.
main :: IO ()
main = do
db <- initTodosDatabase
run 3000 $ do
liveApp quickStartDocument (runTodosSQLite db $ runPage page)
Whichever implementation we use, a
HyperView or
Page can interact with the data using the same high-level
Todos effect by adding it as a constraint:
{-# LANGUAGE UndecidableInstances #-}
simplePage :: (Todos :> es) => Page es '[AllTodos, TodoView]
simplePage = do
todos <- send Todos.LoadAll
pure $ do
hyper AllTodos $ todosView FilterAll todos
-
-
Todos - Implemented with Session
-