Reputation: 83
I need some wrapped on IO type, but I can not 'force' haskell to run IO action in wrapper. I tried using bang pattern for it, but it also does not work.
I recreated problem on much simpler type. Code snippet below
{-# LANGUAGE BangPatterns #-}
newtype IOWrapper a = IOWrapper (IO a)
mkWrapper :: IO a -> IOWrapper a
mkWrapper !a = IOWrapper a
foo :: IO ()
foo = putStrLn "foo" --Shows "foo" on console, as expected
bar :: IOWrapper ()
bar = IOWrapper $ putStrLn "bar" --Shows nothing
baz :: IOWrapper ()
baz = mkWrapper $ putStrLn "baz" --Shows nothing
Upvotes: 1
Views: 285
Reputation: 80805
Merely calling putStrLn "foo"
does not actually print "foo". Instead, it creates an "action", which then has to be separately "executed", and only then will it print "foo". Moreover, you can actually "execute" it multiple times, and the effect will be produced multiple times as well.
And the only way to "execute" an IO
action is to make it the entry point - i.e. the main
function - or part of the entry point, or part of another function, which is itself part of the entry point, and so on. The entry point is the root of all effects, there is no effect execution outside of it.
Your foo
function probably appears to "work" because you're running it in GHCi, right? If so, then it's executed as part of GHCi's own entry point. GHCi recognizes things of IO
type and executes them right away.
But GHCi does not recognize things of the IOWrapper
type, so it doesn't unwrap and execute them.
So the only way for you to go is to unwrap and execute yourself:
runIOWrapper :: IOWrapper a -> IO a
runIOWrapper (IOWrapper a) = a
Then you can run your wrapped actions in GHCi like this:
> runIOWrapper bar
bar
> runIOWrapper baz
baz
Upvotes: 6
Reputation: 92117
You cannot do this (without cheating). Evaluating IO does not cause it to perform its effects. The only thing that causes IO to perform effects is to include it in the special action main :: IO a
, usually by combining a number of smaller actions into one large IO action.
Instead of asking how to do this thing, back up and think about why you want to do it. Ask instead how to accomplish your original goal.
Upvotes: 5