This is a repost of my previous question(deleted by myself) since I considered it would be adequate to change the focus by presenting the sample code below.
Basically, I try to implement a Functor that takes a function such as id
, \a -> a + 1
or even print
.
So the function type can be
f:: a -> b
f:: a -> IO ()
module Main where
import Control.Monad.Primitive (PrimMonad (PrimState))
import qualified Data.Vector.Mutable as M
import System.IO.Error (isDoesNotExistErrorType)
main :: IO ()
main = do
let ioA = io (5 :: Int)
let f = print
-- f = \a -> a + 1
let ioB = someFunctor f ioA
ioB
print "done"
data R a = R
{ val :: M.MVector (PrimState IO) a
}
io :: a -> IO (R a)
io = \a -> do
val <- M.new 1
M.write val 0 a
return $ R val
_val :: R a -> IO a
_val = \ra -> M.read (val ra) 0
someFunctor :: Show a => (a -> b) -> IO (R a) -> IO (R b)
someFunctor = \f -> \ioA -> do
print "-- someFunctor"
val <- ioA >>= _val
print val --works 5
let ioB = io $ f val
--here, I want to actually `print val` when `f == print`
return $ f val
ioB
Output
"-- someFunctor"
5
"done"
The current sample code woks without errors, and what I want to achieve is to evaluate
f val
where
f val
is the value wrapped into the new container ioB
: io $ f val
However, due to the lazy-evaluation strategy of Haskell or some other reason, when f == print
, this is not actually performed, so the val
is not printed against my expectation.
So far, I did return $ f val
, but this does not work unlike the working print val
.
Just f val
in do
thread doesn't go well because f
can be id
and in that case, it's not IO
type. Type mismatch. The compiler smartly generates an error here thanksfully.
So, my question is what is the generic way to implement f val
to be evaluated when f == print
f:: a -> IO ()
?
If you want to do IO
, you have to admit you're doing IO
.
someFunctor :: Show a => (a -> IO b) -> IO (R a) -> IO (R b)
someFunctor = \f -> \ioA -> do
{- ... -}
b <- f val
io b
You can lift non- IO
functions to IO
ones with return
, as in
someFunctor (return . id)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.