To pattern match on the value, you must bind its result within the given monad, the exact same way you did within your Monad
instance:
interpret :: FlowT m a -> m a
interpret flow = do
value <- runFlowT flow
case value of
Continue v -> ...
Return r -> ...
As a side note, you've reinvented a special case of free monad transformers, and you can find the official implementation of them in the free
package.
Specifically, your FlowT
type is identical to:
import Control.Monad.Trans.Free -- from the 'free' package
import Data.Functor.Constant -- from the 'transformers' package
type FlowT = FreeT (Constant Value)
This gives an isomorphic type with the exact same behavior and the same Monad
and MonadTrans
instances.
But back to your specific question: No, there is no way to pattern match on the value without binding the result within the base monad first.