2016-04-19 11 views
2

への暗黙を利用できるようにする方法を、私は暗黙の多用(実際spire.mathライブラリ)を行うコードをコンパイルしようとしている。これらが、スカラ座(ランタイム)relectionのAPIを使用して反射

val src = "(a: spire.math.Jet[Double],b: spire.math.Jet[Double]) => a + b" 
    println(toolBox.eval(toolBox.parse(src))) 

暗黙のはtoolbox.evalが呼び出されるスコープ内に表示され、反射コンパイルがまだ失敗:

could not find implicit value for parameter f: spire.algebra.Field[Double] 

は、どのように私はツールボックスにこの情報を利用することができますか?

+0

目的は何ですか? – cchantep

+0

@cchantep - 明確にするために編集されました。 – NietzscheanAI

答えて

3

この質問に答える前に、まずScalaのバージョンを修正して質問を再現できるようにしてください。 Scala 2.11.8、sbt 0.13.11、spire-math 0.11.0を使用すると仮定しましょう。

その後裸build.sbtは次のようになります。

name := "test" 

version := "1.0" 

scalaVersion := "2.11.8" 

libraryDependencies += "org.scala-lang" % "scala-compiler" % scalaVersion.value 

libraryDependencies += "org.spire-math" %% "spire" % "0.11.0" 

とあなたのコードは次のように見て、Test.scalaファイルに保存することができます:sbt runを実行する際に

import spire.implicits._ 
import scala.reflect.runtime.currentMirror 
import scala.tools.reflect.ToolBox 

object Test { 
    def main(args: Array[String]) = { 
    val toolBox = currentMirror.mkToolBox() 
    val src =""" 
     |(a: spire.math.Jet[Double],b: spire.math.Jet[Double]) => a + b 
     """.stripMargin 
    println (toolBox.eval(toolBox.parse(src))) 
    } 
} 

、あなたが得ます:

$ sbt run 
[info] Running Test 
[error] scala.tools.reflect.ToolBoxError: reflective compilation has failed: 
[error] could not find implicit value for parameter f: spire.algebra.Field[Double] 

したがって、あなたの質問は、なぜですかimport spire.implicits._で定義された暗黙が、toolBoxがインスタンス化され、evalが呼び出されるスコープに含まれているにもかかわらず、失敗します。

あなたのユースケースでは、コンパイラが独立して呼び出される2つの段階があります。第1段階はTest.scalaのコンパイルであり、第2段階はコンパイルと実行です(a: spire.math.Jet[Double],b: spire.math.Jet[Double]) => a + b

この2つのステージは同じランタイムで動作しません。最初の段階では、コンパイラはTest.scalaファイルをコンパイルするために呼び出され、2番目のコンパイラはsrc文字列をコンパイルするためにJVMランタイム内で呼び出されます。その結果、これらの2つのステージは異なるランタイムで実行されるため、同じスコープを共有しません。

この問題の1つの迅速な解決策は、第2段階の範囲内に含意を「再導入する」ことです。

import spire.implicits._ 
import scala.reflect.runtime.currentMirror 
import scala.tools.reflect.ToolBox 

object Test { 
    def main(args: Array[String]) = { 
    val toolBox = currentMirror.mkToolBox() 
    val src =""" 
     |import spire.implicits._ 
     |(a: spire.math.Jet[Double],b: spire.math.Jet[Double]) => a + b 
     """.stripMargin 
    println (toolBox.eval(toolBox.parse(src))) 
    } 
} 

に結果:これは、あなたの質問に答える

​​

希望言い換えれば、あなたがコンパイルしようとする文字列でimport spire.implicits._を付加しました。 Scalaコンパイラがスコープ内のインプリシットをどのように検索しているかについての詳細な解答が好きなら、良いスタートはhereです。

関連する問題