TemplateHaskell和IO [英] TemplateHaskell and IO
问题描述
如果他们使用副作用,是否有任何正确的方法使TH的功能安全?说,我想有一个函数,在编译时调用git并生成一个版本字符串:
{ - #LANGUAGE TemplateHaskell# - }
module Qq where
import System.Process
import Language.Haskell.TH
version = $([|( readProcessgit[rev-parse,HEAD])|])
版本的类型是IO String。但版本在运行时完全没有副作用,
仅在编译时才有副作用。有没有办法在不使用unsafePerformIO的情况下使其在运行时是纯粹的?
现在,要运行此命令而不使用unsafePerformIO,请使用 runIO 一>。您将不得不自己构建Expr,而不使用[| |](这也解决了类型问题)。
其实,如果你使用[| |]来插入一个IO计算,我认为它只会插入计算,而不是运行它。但这是不相干的,因为无论它做什么,这都不是做你想做的事的正确方法。
Is there any proper way to make TH's functions safe if they use side effects? Say, I want to have a function that calls git in compile time and generates a version string:
{-# LANGUAGE TemplateHaskell #-}
module Qq where
import System.Process
import Language.Haskell.TH
version = $( [| (readProcess "git" ["rev-parse", "HEAD"] "") |] )
the type of version is IO String. But version is completely free of side effects in runtime, it has side effects only in compile time. Is there any way to make it pure in runtime without using unsafePerformIO ?
First: normally, the runtime type of the generated code is independent of the compile-time type of the Template Haskell subexpressions, so the runtime type doesn't have to be in IO.
Now, to run this command without using unsafePerformIO, use runIO. You will then have to construct the Expr yourself, without using [| |] (this also solves the type problem).
Actually, if you use [| |] to insert an IO computation, I think it will only insert the computation, not run it, anyway. But that's an irrelevant aside, because regardless of what it does, that's not the right way to do what you want to do.
这篇关于TemplateHaskell和IO的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!