這是對我之前的問題(由我自己洗掉)的重新發布,因為我認為通過提供下面的示例代碼來改變焦點就足夠了。
基本上,我嘗試實作一個Functor,它采用諸如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。只是
f val在do執行緒中并不順利,因為f可以id,在這種情況下,它不是IO型別。型別不匹配。謝天謝地,編譯器在這里巧妙地生成了一個錯誤。所以,我的問題是什么時候進行評估的通用方法是什么?
f valf == printf :: a -> IO ()
uj5u.com熱心網友回復:
如果你想做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具有 的功能return,如
someFunctor (return . id)
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/427282.html
標籤:哈斯克尔
