TemplateHaskell和IO [英] TemplateHaskell and IO

查看:84
本文介绍了TemplateHaskell和IO的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果他们使用副作用,是否有任何正确的方法使TH的功能安全?说,我想有一个函数,在编译时调用git并生成一个版本字符串:

  { - #LANGUAGE TemplateHaskell# - } 

module Qq where

import System.Process
import Language.Haskell.TH

version = $([|( readProcessgit[rev-parse,HEAD])|])

版本的类型是IO String。但版本在运行时完全没有副作用,
仅在编译时才有副作用。有没有办法在不使用unsafePerformIO的情况下使其在运行时是纯粹的?

第一:通常,生成的代码的运行时类型与模板Haskell子表达式的编译时类型无关,所以运行时类型不必在IO中。



现在,要运行此命令而不使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆