首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >`f ::-> IO ()‘在do线程中的求值: Haskell

`f ::-> IO ()‘在do线程中的求值: Haskell
EN

Stack Overflow用户
提问于 2022-02-07 13:26:14
回答 1查看 112关注 0票数 1

这是我上一个问题的重新发布(我自己删除了),因为我认为通过下面的示例代码来改变焦点就足够了。

基本上,我尝试实现--一个接受id\a -> a + 1甚至print等函数的函子。

所以函数类型可以是

f :: a -> b

f :: a -> IO ()

代码语言:javascript
复制
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

输出

代码语言:javascript
复制
"-- someFunctor"
5
"done"

当前的示例代码工作正常,我想要实现的是评估

f val

哪里

  1. f val是包装到新容器ioBio $ f val

中的值。

然而,由于Haskell的惰性评估策略或其他原因,当expectation.没有实际执行时,

  1. 就没有执行,所以val不是针对我的f == print打印的。

到目前为止,我使用了print val.,但这与

  1. 不同

  1. 只是do线程中的f val并不顺利,因为f可以是id,在这种情况下,它不是IO类型。类型错配。编译器在这里巧妙地生成一个错误,thanksfully.

因此,我的问题是,在f :: a -> IO ()

  1. 时,实现要评估的f val的通用方法是什么?
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-02-07 15:06:41

如果你想做IO,你必须承认你在做IO

代码语言:javascript
复制
someFunctor :: Show a => (a -> IO b) -> IO (R a) -> IO (R b)
someFunctor = \f -> \ioA -> do
    {- ... -}
    b <- f val
    io b

您可以使用IO将非IO函数提升到IO函数,如

代码语言:javascript
复制
someFunctor (return . id)
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71019336

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档