Is possible to get a value out of a Handler Monad?

14 views
Skip to first unread message

Conee

unread,
Mar 11, 2021, 7:44:16 AM3/11/21
to Yesod Web Framework
Hi,
Although I haven't fully understood yet, it seems that everything that is obtained from the database with the runDB and get404 functions is wrapped in a handler monad.
I need a value from the database which is of type Text, but I only managed to get the
Handler Text which is causing me a problem.
I'm probably complicated, but I'm a beginner, so I'm experimenting.
I have the following functions:

getCityFromMan :: Manifestation -> Handler Text   --I want here to be just Text type getCityFromMan man = do
       loc <- runDB $ get404 $ manifestationLocation man   --Manifestation has key to Location 
       ads <- runDB $ get404 $ locationAddress loc --Location has key to Address       
       let cityName = addressCity ads --Address has column city type Text
       return cityName    

applyFilters :: ManFilter -> Manifestation -> Bool
applyFilters f man = and
       [ go name filterSearch
        , go city filterCity ]
  where
        go :: (z -> Bool) -> (ManFilter -> Maybe z) -> Bool
        go x y =
             case y f of
               Nothing -> True
               Just z -> x z
         norm = T.filter validChar . T.map C.toLower . normalize NFKD
         validChar = not . C.isMark
         name x = norm x `T.isInfixOf` norm (manifestationName man)  -- working ok
         city' = getCityFromMan man    --want to get name of city in Text type but its type is HandlerFor Text
         city x = norm x == norm city'    --get true if filter value and city is the same

I get error:

Couldn't match typeHandlerFor App Text’ with ‘Text
Expected type: Text        Actual type: Handler Text

How to deal with this and is it even possible to extract Text from Handler Text?
On several similar problems I have seen that it is not possible, then what is the solution??
Thanks a lot, any advice is welcome.

Conee

unread,
Mar 11, 2021, 9:41:56 AM3/11/21
to Yesod Web Framework
typing error in first function:
getCityFromMan :: Manifestation -> Handler Text    -- I want here to be just Text type
getCityFromMan man = do
       loc <- runDB $ get404 $ manifestationLocation man    --Manifestation has key to Location 
       ads <- runDB $ get404 $ locationAddress loc   --Location has key to Address       
       let cityName = addressCity ads   --Address has column city type Text
       return cityName   

jsch...@gmail.com

unread,
Mar 12, 2021, 3:21:52 AM3/12/21
to Yesod Web Framework
Conee schrieb am Donnerstag, 11. März 2021 um 15:41:56 UTC+1:
typing error in first function:
getCityFromMan :: Manifestation -> Handler Text    -- I want here to be just Text type

That's not possible: If you could return just Text, then it would be a pure function. A database operation can never be a pure function.

Conee

unread,
Mar 12, 2021, 10:16:46 AM3/12/21
to Yesod Web Framework
Thanks for your reply !
In the meantime, someone find me solution, although I don't fully understand the filterM and pure functions, since I'm a beginner, but this is working now.


applyFilters :: ManFilter -> Manifestation -> Handler Bool
applyFilters f man =
   city' <- getCityFromMan man
   let city x = norm x == norm city'
   pure $ and
       [ go name filterSearch
        , go city filterCity ]
  where
        go :: (z -> Bool) -> (ManFilter -> Maybe z) -> Bool
        go x y =
             case y f of
               Nothing -> True
               Just z -> x z
         norm = T.filter validChar . T.map C.toLower . normalize NFKD
         validChar = not . C.isMark
         name x = norm x `T.isInfixOf` norm (manifestationName man)  -- working ok

postManUserR :: Handler Html
postManUserR = do
   emans <- runDB getAllMan
   let mans = toValues emans
   filters <- runInputPost $ ManFilter
     <$>iopt textField "City"
     <*>iopt textField "Search"
   filteredMan <- filterM (applyFilters filters) mans
   defaultLayout $ do
     [whamlet|<h1>#{show $ filteredMan}|]

Reply all
Reply to author
Forward
0 new messages