Haskell - 将任意函数和参数列表作为参数传递给另一个函数

时间:2016-09-02 13:16:15

标签: function variables haskell arguments

我的主要目标是将stderr重定向到文件。

我抓住了以下代码段...

catchOutput :: IO a -> IO (res, String)
catchOutput f = do
  tmpd <- getTemporaryDirectory
  (tmpf, tmph) <- openTempFile tmpd "haskell_stderr"
  stderr_dup <- hDuplicate stderr
  hDuplicateTo tmph stderr
  hClose tmph
  res <- f
  hDuplicateTo stderr_dup stderr
  str <- readFile tmpf
  removeFile tmpf
  return (res, str)

我希望这更通用,并将任何函数和参数列表传递给catchOutput并获取函数结果以及写入stderr的消息(如果有的话)。

我认为[Data.Dynamic]类型的参数列表可能有用,但我无法使用

检索函数结果
res <- Data.List.foldl (f . fromDyn) Nothing $ args

这甚至可能吗?非常感谢帮助。

1 个答案:

答案 0 :(得分:3)

没有理由使用Data.Dynamic。您已经知道输入f的返回类型,它是a所以您可以使用它,即

catchOutput :: IO a -> IO (a, String)

但请注意,您的方法存在一些重大问题:

  1. 通过将stderr重定向到文件,这也会影响所有其他并发线程。因此,您可能会将不相关的数据发送到临时文件。
  2. 如果在重定向stderr时抛出异常,则原始stderr将无法恢复。在这种情况下,两个hDuplicateTo行(hClosef)之间的任何操作都可能抛出异常,或者线程可能会收到异步异常。因此,您必须使用类似bracket的内容来使代码异常安全。