[英]`f :: a -> IO ()` evaluation in do thread : Haskell
這是我之前問題(被我自己刪除)的轉貼,因為我認為通過下面的示例代碼來改變焦點就足夠了。
基本上,我嘗試實現一個采用 function 的 Functor,例如id
、 \a -> a + 1
甚至print
。
所以 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
"-- someFunctor"
5
"done"
當前的示例代碼沒有錯誤,我想要實現的是評估
f val
在哪里
f val
是包裝到新容器ioB
中的值: io $ f val
但是,由於 Haskell 的惰性評估策略或其他原因,當f == print
時,實際上並未執行此操作,因此未按我的預期打印val
。
到目前為止,我確實return $ f val
,但這與工作中的print val
不同。
do
thread 中的f val
不是 go,因為f
可以是id
,在這種情況下,它不是IO
類型。 類型不匹配。 值得慶幸的是,編譯器在這里巧妙地產生了一個錯誤。
所以,我的問題是,當f == print
f:: a -> IO ()
時,實現要評估的f val
的通用方法是什么?
如果你想做IO
,你必須承認你正在做IO
。
someFunctor :: Show a => (a -> IO b) -> IO (R a) -> IO (R b)
someFunctor = \f -> \ioA -> do
{- ... -}
b <- f val
io b
您可以使用return
將非IO
函數提升為IO
函數,如
someFunctor (return . id)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.