[英]`f :: a -> IO ()` evaluation in do thread : Haskell
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
.基本上,我尝试实现一个采用 function 的 Functor,例如
id
、 \a -> a + 1
甚至print
。
So the function type can be所以 function 类型可以是
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 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
f val
是包装到新容器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.但是,由于 Haskell 的惰性评估策略或其他原因,当
f == print
时,实际上并未执行此操作,因此未按我的预期打印val
。
So far, I did return $ f val
, but this does not work unlike the working print val
.到目前为止,我确实
return $ f val
,但这与工作中的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. do
thread 中的f val
不是 go,因为f
可以是id
,在这种情况下,它不是IO
类型。 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 ()
?所以,我的问题是,当
f == print
f:: a -> IO ()
时,实现要评估的f val
的通用方法是什么?
If you want to do IO
, you have to admit you're doing IO
.如果你想做
IO
,你必须承认你正在做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您可以使用
return
将非IO
函数提升为IO
函数,如
someFunctor (return . id)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.