首先抱歉我的英语,以及我试图学习Haskell的事实
我会从java运行Frege代码(Haskell),几乎所有 方面我设法使所有工作按照指示找到 在各种网站上...但我仍然有一个关于以下代码的问题, 对于请求的冗长感到抱歉...
$xml = [xml]'
<Events>
<Event Definition="Validate" DLLPath="" DLLName="Helper.dll" DLLClass="HelpMain" DLLRoutine="pgFeatureInfoOnValidate_WriteToRegSelectedFeatures" InputParameters="pTreeViewFeatureTreeServerOS" RunOnce="no"/>
<Event Definition="Validate1" DLLPath="" DLLName="Helper.dll1" DLLClass="HelpMain1" DLLRoutine="pgFeatureInfoOnValidate_WriteToRegSelectedFeatures" InputParameters="pTreeViewFeatureTreeServerOS" RunOnce="no"/>
</Events>
'
Select-XML -xml $xml -xpath "//Event/@DllName"
package local.java;
import java.io.PrintWriter;
import java.util.Arrays;
import frege.runtime.Runtime;
import frege.runtime.Runtime.*;
import frege.java.Util.TList;
import frege.prelude.PreludeArrays;
import frege.prelude.PreludeBase;
import frege.control.monad.State;
import frege.run7.*;
import local.frege.FregeHelloTest;
public class JavaHelloTest {
public static void main(String[] args) {
System.out.println("Hello World from Java code ... ");
System.out.println("========================");
System.out.println("callingMain0 ... ");
System.out.println("------------------------");
FregeHelloTest.callingMain0(Thunk.<PreludeBase.TList<String>>lazy(PreludeArrays.IListSource_JArray.<String>toList(args)));
System.out.println("========================");
System.out.println("callingMain1 ... ");
System.out.println("------------------------");
FregeHelloTest.callingMain1(Thunk. <PreludeBase.TList<String>>lazy(PreludeArrays.IListSource_JArray.<String>toList(args)));
System.out.println("========================");
System.out.println("callingMain2 ... ");
System.out.println("------------------------");
FregeHelloTest.callingMain2(Thunk. <PreludeBase.TList<String>>lazy(PreludeArrays.IListSource_JArray.<String>toList(args)));
System.out.println("========================");
}
}
module local.frege.FregeHelloTest where
import Prelude.PreludeBase as PreludeBase
main :: [String] -> IO ()
main args = println $ "Hello World from Frege code ..."
callingMain0 :: [String] -> ()
callingMain0 ss = PreludeBase.ST.performUnsafe(main ss)
callingMain1 :: [String] -> IO ()
callingMain1 ss = return ( PreludeBase.ST.performUnsafe(main ss) )
callingMain2 :: [String] -> ()
callingMain2 ss = PreludeBase.ST.run( return ( PreludeBase.ST.performUnsafe(main ss) ) )
程序输出...带入口点:local.java.JavaHelloTtest.main
{ ... omissis ... }
final public class FregeHelloTest {
final public static Func.U<RealWorld, Short> $main(final Lazy<PreludeBase.TList<String/*<Character>*/>> arg$1) {
return PreludeBase.<Func.U<RealWorld, Short>, String/*<Character>*/>$(
new Func.U.D<String/*<Character>*/, Func.U<RealWorld, Short>>() {
public Lazy<Func.U<RealWorld, Short>> apply(final Lazy<String/*<Character>*/> η$7611) {
return Thunk.<Func.U<RealWorld, Short>>shared(
new Lazy.D<Func.U<RealWorld, Short>>() {
public Func.U<RealWorld, Short> call() {
return Prelude.<String/*<Character>*/>println(PreludeText.IShow_String.it, η$7611.call());
}
}
);
}
},
Thunk.<String/*<Character>*/>lazy("Hello World from Frege code ...")
).call();
}
final public static short callingMain2(final Lazy<PreludeBase.TList<String/*<Character>*/>> arg$1) {
return (short)PreludeBase.TST.<Short>run(
PreludeMonad.IMonad_ST.<Object, Short>pure(
Thunk.<Short>nested(
new Lazy.D<Lazy<Short>>() {
public Lazy<Short> call() {
return PreludeBase.TST.<Short>performUnsafe(FregeHelloTest.$main(arg$1));
}
}
)
)
).call();
}
final public static Func.U<RealWorld, Short> callingMain1(final Lazy<PreludeBase.TList<String/*<Character>*/>> arg$1) {
return PreludeMonad.IMonad_ST.<RealWorld, Short>pure(
Thunk.<Short>nested(
new Lazy.D<Lazy<Short>>() {
public Lazy<Short> call() {
return PreludeBase.TST.<Short>performUnsafe(FregeHelloTest.$main(arg$1));
}
}
)
);
}
final public static short callingMain0(final Lazy<PreludeBase.TList<String/*<Character>*/>> arg$1) {
return (short)PreludeBase.TST.<Short>performUnsafe(FregeHelloTest.$main(arg$1)).call();
}
public static void main(final java.lang.String[] argv) { ... omissis ... }
}
经过不久(对我来说)的调查,我意识到这是正确的
&#34; CallingMain1&#34;没有执行任何事情......事实上,正如你所看到的那样
由&#34; callingMain2&#34;生成需要一个&#34;运行&#34; ......但如果我试试
使用&#34; run&#34;执行,返回&#34; callingMain1&#34; IDE
(Eclipse然后编译器)告诉我签名不正确,
PreludeBase.TST。&lt; Short&gt; run is on&#34; Object&#34;而不是&#34; RealWorld&#34;,
实际上,编译器在&#34; callingMain2&#34;设置一个
&#34;对象&#34;而不是&#34; RealWorld&#34;运行callingMain2。
显然(我认为)&#34; callingMain1&#34;的签名(Haskell)是正确的 ... 我认为没有人能碰到......
现在问题......在这一点上,我认为,也许应该如此 一个功能... TST.runOnRealWorld允许评估 IO()从尚未返回&#34; callingMain1&#34 ;;然而,就像在这一代 &#34; callingMain2&#34;我清楚地看到操作已经改变 即时#34;对象&#34;我必须假设这个功能不存在......
这是需要的,或者只是需要添加&#34;运行&#34;方法 允许java评估&#34; callingMain1&#34;的输出。 ?
或者,更可能的是,我很少理解......非常感谢...
答案 0 :(得分:1)
首先,我想说没有必要为学习Haskell而感到遗憾。与此相反的。认为自己属于精英,内裤!
为callingMain0
生成的java代码是从Java运行I / O操作的正确代码。我建议直接使用它(或通过Java实用程序方法),并且出于卫生原因,没有看似纯粹的辅助函数,如callingMain0
。
顺便说一下,当你传递一个具有弗雷格代数数据类型的值(枚举除外)时,你不需要将它包装在额外的Thunk.<...>lazy()
中,因为所有这些类型都已经实现了{ {1}}界面。所以你可以写:
Lazy
无论函数是否实际需要惰性列表或严格列表,都可以使用。
接下来,FregeHelloTest.callingMain0(PreludeArrays.IListSource_JArray.<String>toList(args));
当然,它什么都不做,就像
callingMain1
什么都不做。为什么?因为类型是FregeHelloTest.$main(...)
此类型告诉我们该函数返回一个操作,该操作在执行该操作时将产生IO ()
。在弗雷格执行IO操作的唯一方式是()
。但是,您不会将操作(即调用PreludeBase.TST.<T>performUnsafe
的结果)传递给callingMain1(...)
。因此,行动永远不会被执行。
备注:当您检查为Frege模块生成的代码时,您可能已经注意到存在performUnsafe
方法。如果没有,请查阅。您将看到JVM输入的main
方法只是通过将结果传递给main
来调用$main
(对应于您的Frege main
函数) 。没有其他办法。
还有一句话:存在一个广泛存在的误解,即具有performUnsafe
类型的Haskell(或Frege)函数是不纯的。你在这里看到这是完全错误的。您可以根据需要随时调用IO
函数,除了构造IO
操作外,什么都不会发生。这绝对是纯粹的。对于相同的论点,你将获得相同的&#34;相同的&#34; (在行为方面,因为我们可以比较它们)IO
行动回来,并且不会发生副作用直到实际执行此类行为。
但是,你会问,为什么IO
函数中的performUnsafe
什么都不做?这是因为callingMain1
是懒惰的。根本没有理由评估它的论点。这也表明return
在弗雷格代码中确实是不安全的,并且关于何时以及将以何种顺序评估所有赌注都是关闭的。再举一个例子,试试:
performUnsafe
最后,tail [IO.performUnsafe $ print "Ha"]
这是最令人困惑的,我不确定你在想什么。 calingMain2
只会运行幻像类型中具有多态性的真实ST.run
操作。现在,当然,您通过说
ST
操作
ST
和return IO.performUnsafe(main args)
确实运行了此操作,从而评估了ST.run
。
但您无法将performUnsafe
应用于ST.run
行动。考虑
IO
当你说:
type IO = ST RealWorld
ST.run :: (forall s. ST s a) -> a
这不会起作用,因为ST.run(print "foo")
不像RealWorld
那样具有多态性。
幸运的是,你也不能用Java作弊,因为s
不是Func<RealWorld,Short>
的子类型
最后,我想重新迭代:要从Java运行IO操作,除了将其传递给Func<Object,Short>
希望这有帮助,随时可以询问尚不清楚的事情。