简体   繁体   English

`f:: a -> IO ()` 在执行线程中的评估:Haskell

[英]`f :: a -> IO ()` evaluation in do thread : Haskell

This is a repost of my previous question(deleted by myself) since I considered it would be adequate to change the focus by presenting the sample code below.这是我之前问题(被我自己删除)的转贴,因为我认为通过下面的示例代码来改变焦点就足够了。

Basically, I try to implement a Functor that takes a function such as id , \a -> a + 1 or even print .基本上,我尝试实现一个采用 function 的 Functor,例如id\a -> a + 1甚至print

So the function type can be所以 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 Output

"-- someFunctor"
5
"done"

The current sample code woks without errors, and what I want to achieve is to evaluate当前的示例代码没有错误,我想要实现的是评估

f val

where在哪里

  1. f val is the value wrapped into the new container ioB : io $ f val f val是包装到新容器ioB中的值: io $ f val

  2. However, due to the lazy-evaluation strategy of Haskell or some other reason, when f == print , this is not actually performed, so the val is not printed against my expectation.但是,由于 Haskell 的惰性评估策略或其他原因,当f == print时,实际上并未执行此操作,因此未按我的预期打印val

  3. So far, I did return $ f val , but this does not work unlike the working print val .到目前为止,我确实return $ f val ,但这与工作中的print val不同。

  4. Just f val in do thread doesn't go well because f can be id and in that case, it's not IO type. do thread 中的f val不是 go,因为f可以是id ,在这种情况下,它不是IO类型。 Type mismatch.类型不匹配。 The compiler smartly generates an error here thanksfully.值得庆幸的是,编译器在这里巧妙地产生了一个错误。

  5. So, my question is what is the generic way to implement f val to be evaluated when f == print f:: a -> IO () ?所以,我的问题是,当f == print f:: a -> IO ()时,实现要评估的f val通用方法是什么?

If you want to do IO , you have to admit you're doing IO .如果你想做IO ,你必须承认你正在做IO

someFunctor :: Show a => (a -> IO b) -> IO (R a) -> IO (R b)
someFunctor = \f -> \ioA -> do
    {- ... -}
    b <- f val
    io b

You can lift non- IO functions to IO ones with return , as in您可以使用return将非IO函数提升为IO函数,如

someFunctor (return . id)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM