这是我上一个问题的重新发布(我自己删除了),因为我认为通过下面的示例代码来改变焦点就足够了。
基本上,我尝试实现--一个接受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的惰性评估策略或其他原因,当expectation.没有实际执行时,
val不是针对我的f == print打印的。到目前为止,我使用了print val.,但这与
do线程中的f val并不顺利,因为f可以是id,在这种情况下,它不是IO类型。类型错配。编译器在这里巧妙地生成一个错误,thanksfully.。
因此,我的问题是,在f :: a -> IO ()
f val的通用方法是什么?发布于 2022-02-07 15:06:41
如果你想做IO,你必须承认你在做IO。
someFunctor :: Show a => (a -> IO b) -> IO (R a) -> IO (R b)
someFunctor = \f -> \ioA -> do
{- ... -}
b <- f val
io b您可以使用IO将非IO函数提升到IO函数,如
someFunctor (return . id)https://stackoverflow.com/questions/71019336
复制相似问题