Haskell: 如何从IO(a)转换为a?

4

我有一个返回值为 IO (Map.Map String Double) 的函数,我需要的是一个不带 IO 的 Map.Map String Double

我尝试了下面这个方法,但是出现了错误:Not in scope: data constructor `IO'。

extractIO (IO (a)) = a

5
通常情况下,你无法避免使用IO。(如果非常必要,有一种方法可以做到。)IO将纯部分与需要与外部进行交互的“受污染”部分(例如读取文件或获取用户输入)分开。您可以将结果绑定到一个名称上,例如theMap <- thingThatCreatesMap,并在从IO操作调用的纯计算中使用它。 - Daniel Fischer
1
请参考 fmap 函数,它可以让你对 IO 包装的值应用一个函数。当你将 fmap 函数特化为 IO 时,它的类型为:(a -> b) -> IO a -> IO b - Gabriella Gonzalez
1
这个想法是你不从 IO 中获取东西。相反,你使用 Monad 特性将东西推入 IO 中,在那里你可以安全地将它们与必须在 IO 中的值组合(例如,fmap 可以将普通函数 a -> b 转换为函数 IO a -> IO b,然后你可以将其应用于你的 IO a 值)。 - Ben
2个回答

14

你不能仅仅取消IO,这就是IO的全部意义。

如果你有一个IO (Map.Map String Double)对象并想要处理它,你必须在单子上下文中进行处理,也就是说:

stuff :: IO ()
stuff = do
  map <- theThingThatReturnsYourIOMap
  theThingThatNeedsYourUnwrappedMap map

如果您能更详细地解释您想要做什么,我们可以给您提供更详细的答案。


1

1
更好的链接是 http://hackage.haskell.org/packages/archive/base/4.6.0.1/doc/html/System-IO-Unsafe.html#v:unsafePerformIO。 - leventov
10
直接给出这个答案并不是一个好主意。unsafePerformIO是一种后门(专门为特殊目的而创建的),不应该教给尚在学习Haskell的人。相反,他们应该学习如何在Haskell的精神中使用它。 - is7s
3
虽然我认为这不是一个好的答案,但它仍然是一个有效的答案,并且立即附带了必要的警告(尽管或许应该解释一下为什么unsafePerformIO是“不好的想法”)。 - leftaroundabout

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接