do thread 中的`f :: a -> IO ()` 评估:Haskell
`f :: a -> IO ()` evaluation in do thread : Haskell
这是我之前问题的转贴(被我自己删除了),因为我认为通过下面的示例代码来改变焦点就足够了。
基本上,我尝试实现 a 仿函数,它采用 id
、\a -> a + 1
甚至 print
等函数。
所以函数类型可以是
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
输出
"-- someFunctor"
5
"done"
当前的示例代码没有错误,我想达到的是评估
f val
哪里
f val
是包装到新容器中的值ioB
:io $ f val
但是由于Haskell的惰性求值策略或者其他原因,在f == print
时并没有真正执行,所以val
没有按我的预期打印。
到目前为止,我做了 return $ f val
,但这与正在工作的 print val
.
不同
只是 do
线程中的 f val
并不顺利,因为 f
可以是 id
在这种情况下,它不是 IO
类型。类型不匹配。谢天谢地,编译器在这里巧妙地产生了一个错误。
所以,我的问题是 generic 实现 f val
的方法是什么 f == print
f :: a -> IO ()
?
如果你想做 IO
,你必须承认你正在做 IO
。
someFunctor :: Show a => (a -> IO b) -> IO (R a) -> IO (R b)
someFunctor = \f -> \ioA -> do
{- ... -}
b <- f val
io b
您可以将非 IO
函数提升为具有 return
的 IO
函数,如
someFunctor (return . id)
这是我之前问题的转贴(被我自己删除了),因为我认为通过下面的示例代码来改变焦点就足够了。
基本上,我尝试实现 a 仿函数,它采用 id
、\a -> a + 1
甚至 print
等函数。
所以函数类型可以是
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
输出
"-- someFunctor"
5
"done"
当前的示例代码没有错误,我想达到的是评估
f val
哪里
f val
是包装到新容器中的值ioB
:io $ f val
但是由于Haskell的惰性求值策略或者其他原因,在
f == print
时并没有真正执行,所以val
没有按我的预期打印。到目前为止,我做了
不同return $ f val
,但这与正在工作的print val
.只是
do
线程中的f val
并不顺利,因为f
可以是id
在这种情况下,它不是IO
类型。类型不匹配。谢天谢地,编译器在这里巧妙地产生了一个错误。所以,我的问题是 generic 实现
f val
的方法是什么f == print
f :: a -> IO ()
?
如果你想做 IO
,你必须承认你正在做 IO
。
someFunctor :: Show a => (a -> IO b) -> IO (R a) -> IO (R b)
someFunctor = \f -> \ioA -> do
{- ... -}
b <- f val
io b
您可以将非 IO
函数提升为具有 return
的 IO
函数,如
someFunctor (return . id)