TemplateHaskell和IO

voi*_*ard 6 haskell template-haskell

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

{-# LANGUAGE TemplateHaskell #-}

module Qq where

import System.Process
import Language.Haskell.TH

version =  $( [| (readProcess "git" ["rev-parse", "HEAD"] "")  |] )
Run Code Online (Sandbox Code Playgroud)

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

Rob*_*een 7

第一:通常,生成的代码的运行时类型独立于Template Haskell子表达式的编译时类型,因此运行时类型不必在IO中.

现在,要在不使用unsafePerformIO的情况下运行此命令,请使用runIO.然后,您必须自己构建Expr,而不使用[| |](这也解决了类型问题).

实际上,如果你使用[| 插入IO计算,我认为它只会插入计算,而不是运行它.但这是无关紧要的,因为无论它做什么,这都不是做你想做的事情的正确方法.

  • 作为练习,我试着想出这里描述的代码.也许它对其他人也很有用,所以在这里:`version =(stringE.init)= <<(runIO $ readProcess"git"["rev-parse","HEAD"]"")`并使用`$(在一个不同的模块中``字符串表达式可以是. (5认同)