问题
I am having some trouble dealing with the forall
quantifier in ST
's type. The following (simplified) code sample works fine, producing the expected result.
import Control.Monad
import Control.Monad.ST
return' :: a -> ST s a
return' = return
function :: a -> a
function x = runST $ do
-- Some complicated expression eventually producing a result
return' x
This is fine, if all I want to do is have ST
. But in my computation, I want a state transformer computation that might also fail, so I attempt to add ExceptT
to the stack.
import Control.Monad
import Control.Monad.ST
import Control.Monad.Except
return' :: a -> ExceptT String (ST s) a
return' = return
function :: a -> Either String a
function x = runST . runExceptT $ do
-- Some complicated expression that might fail
return' x
Unfortunately, I get a rather bizarre error message.
example.hs:9:14:
Couldn't match type `ST s0 (Either String a)'
with `forall s. ST s (Either String a)'
Expected type: ST s0 (Either String a) -> Either String a
Actual type: (forall s. ST s (Either String a))
-> Either String a
Relevant bindings include
x :: a (bound at example.hs:9:10)
function :: a -> Either String a (bound at example.hs:9:1)
In the first argument of `(.)', namely `runST'
In the expression: runST . runExceptT
I have only a vague understanding of the rank-2 type used by ST
, so I'm not really sure how to approach this error. How can I safely put ST
at the bottom of a monad transformer stack without getting problems with the forall
?
(For those curious, I'm using ST
because I want my computation to use a mutable array and then freeze it at the end. That shouldn't be relevant to this problem, but this is why I can't simply use State
instead)
回答1:
All you need to do is replace the .
behind runST
by $
, and then you can use ordinary return
instead of return'
as well.
import Control.Monad
import Control.Monad.ST
import Control.Monad.Except
function :: a -> Either String a
function x = runST $ runExceptT $ do
return x
main = return ()
(At least for me this compiles, without problems.)
See this answer for the theory behind the error.
来源:https://stackoverflow.com/questions/32654814/trouble-with-sts-type-in-a-transformer-stack