I try to return a uuid within a route definition for a web app (Spock Webserver).
A route is pretty simple to define
get("PATH") $ do
text "Hello World"
Now I try to return a uuid via nextRandom
from the Data.UUID.V1 module.
The function returns a IO(Maybe UUID)
value.
So I thought, since I am in IO and work with another IO I have to do bind the value simply with <-
, like so:
get ("id") $ do
uuid<-nextUUID
json . pack $ show $ uuid
But the compiler says no:
Couldn't match type ‘ActionCtxT ctx0 m0’ with ‘IO’
Expected type: IO b0
Actual type: ActionCtxT ctx0 m0 b0
• In a stmt of a 'do' block: json . pack $ show $ uuid
In the second argument of ‘($)’, namely
‘do { uuid <- nextUUID;
json . pack $ show $ uuid }’
Why is it throwing that error? I could easily create the uuid with a simple print example, but within Spock I don't understand what the ActionCtxT does and why I can't do the uuid IO in it.
So I thought, since I am in IO and work with another IO
That's the trouble here, when you're routing in Spock, you're not in IO. The error message tells you what context you're really in: ActionCtxT ctx0 m0
. According to the docs, that's a monad transformer stack that bundles effects and state.
You can "lift" an IO computation into the right type using liftIO
.
get ("id") $ do
uuid <- liftIO nextUUID
json . pack $ show $ uuid