|
Appendix: Using ghci with HappstackWhen working with Happstack, I seem to spend a lot of time in ghci looking at type signatures, and it's not always obvious what's going on. So I thought I'd share a little mini ghci session in case this helps anyone. *Main> :t query AskDatastore
What you see above are nice looking types. And they can be made concrete, with WebT -- no class class context in the type signature. This is Right. What happens if we try an update on something that should really be a query? Does it get rejected? *Main> :t update AskDatastore
Typechecks with a weird class context, but will complain if run, and impossible to make concrete in ghci using :: to narrow the type. Ugly looking types. This is Wrong. What exactly is askDatastore? *Main> :i askDatastore
what's a Query? Prelude Control.Monad.Reader HAppS.State GHC.Conc> :i Query
that's weird. in the type synonym Query takes a single arg, but in the definition for askDatastore, it took two. I guess the type system uses currying. Let's just substitute the concrete type AppState for the type variables state and see if this mess typechecks. *StateVersions.AppState1 Control.Monad.Reader GHC.Conc Data.Set> :t askDatastore :: Ev (ReaderT AppState STM) (Set User)
No type errors -- it works.
:i ReaderT
The type constructor ReaderT takes three arguments to yield a concrete type.
In the definition for askDatastore, it is partially applied,
with two arguments. ReaderT AppState STM is an instance of Monad,
and also an instance of MonadReader AppState, with AppState as the
reader environment and STM (software transactional memory) as the wrapped monad.
*Main Control.Monad.Reader HAppS.State GHC.Conc> :i ReaderT
What about Ev?... nah.
That is as far down the Happstack type rabbit hole as I am going to go.
|