簡體   English   中英

`f:: a -> IO ()` 在執行線程中的評估:Haskell

[英]`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

在哪里

  1. f val是包裝到新容器ioB中的值: io $ f val

  2. 但是,由於 Haskell 的惰性評估策略或其他原因,當f == print時,實際上並未執行此操作,因此未按我的預期打印val

  3. 到目前為止,我確實return $ f val ,但這與工作中的print val不同。

  4. do thread 中的f val不是 go,因為f可以是id ,在這種情況下,它不是IO類型。 類型不匹配。 值得慶幸的是,編譯器在這里巧妙地產生了一個錯誤。

  5. 所以,我的問題是,當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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM