如何从 java evaluate/run frege IO () monad?
How to evaluate/run frege IO () monad from java?
首先对我的英语感到抱歉,而且我正在努力学习 Haskell
我会 运行 从 java 调用 Frege 代码 (Haskell),几乎所有
我设法按照找到的说明使其全部工作
在各种网站上......但我仍然对以下代码有疑问,
对请求的冗长感到抱歉...
javaHelloTest.java
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("========================");
}
}
fregeHelloTest.fr
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) ) )
fregeHelloTest.java(从 fregec 生成)
{ ... omissis ... }
final public class FregeHelloTest {
final public static Func.U<RealWorld, Short> $main(final Lazy<PreludeBase.TList<String/*<Character>*/>> arg) {
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>*/> η11) {
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, η11.call());
}
}
);
}
},
Thunk.<String/*<Character>*/>lazy("Hello World from Frege code ...")
).call();
}
final public static short callingMain2(final Lazy<PreludeBase.TList<String/*<Character>*/>> arg) {
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));
}
}
)
)
).call();
}
final public static Func.U<RealWorld, Short> callingMain1(final Lazy<PreludeBase.TList<String/*<Character>*/>> arg) {
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));
}
}
)
);
}
final public static short callingMain0(final Lazy<PreludeBase.TList<String/*<Character>*/>> arg) {
return (short)PreludeBase.TST.<Short>performUnsafe(FregeHelloTest.$main(arg)).call();
}
public static void main(final java.lang.String[] argv) { ... omissis ... }
}
程序输出...入口点:local.java.JavaHelloTtest.main
------------------
Hello World from Java code ...
========================
callingMain0 ...
------------------------
Hello World from Frege code ...
========================
callingMain1 ...
------------------------
========================
callingMain2 ...
------------------------
Hello World from Frege code ...
========================
经过长时间的(对我而言)调查,我意识到这是正确的
"CallingMain1" 不执行任何操作...事实上,如您所见
由 "callingMain2" 生成需要 "run" ... 但如果我尝试
使用 "run" 执行,返回 "callingMain1" IDE
(Eclipse 然后是编译器)告诉我签名不正确,
PreludeBase.TST.运行 在 "Object" 而不是 "RealWorld",
事实上,编译器在 "callingMain2" 的情况下设置了一个
"Object" 而不是 "RealWorld" 到 运行 callingMain2.
显然(我认为)"callingMain1" 的签名(Haskell)是正确的...
而且我认为没有人可以触摸...
现在的问题......在这一点上我认为,也许应该是
一个功能... TST.runOnRealWorld 允许评估
IO() 还从"callingMain1" 返回;然而,就像这一代人一样
of "callingMain2" 我清楚地看到操作被改变了
即时 "Object" 我不得不假设这个函数不存在...
这是想要的或者只需要添加一个"run"方法
允许 java 评估 "callingMain1" ?
的输出
或者,更有可能的是,我了解得很少......提前致谢......
首先,我想说没有必要为努力学习而感到遗憾Haskell。从相反的方面来说。认为自己属于精英,insead!
为 callingMain0
生成的 java 代码是 运行 来自 Java 的 I/O 操作的正确代码。我建议直接使用它(或通过 Java 实用方法),出于卫生原因,不要像 callingMain0
这样看似纯粹的辅助函数。
顺便说一句,当你传递一个具有 Frege 代数数据类型的值(枚举除外)时,你不需要将它包装在额外的 Thunk.<...>lazy()
中,因为所有这些类型都已经实现了 Lazy
界面。所以你可以这样写:
FregeHelloTest.callingMain0(PreludeArrays.IListSource_JArray.<String>toList(args));
无论函数实际需要惰性列表还是严格列表,这都有效。
接下来,callingMain1
当然,它什么都不做,就像
FregeHelloTest.$main(...)
什么都不做。为什么?因为类型是 IO ()
这种类型告诉我们函数 returns 一个动作,当该动作被执行时将产生一个 ()
。而在 Frege 中 only 执行 IO 动作的方式是通过 PreludeBase.TST.<T>performUnsafe
。但是您没有将操作(即调用 callingMain1(...)
的结果)传递给 performUnsafe
。因此,该操作永远不会执行。
备注:当您检查为您的 Frege 模块生成的代码时,您可能已经注意到 main
方法的存在。如果没有,请查找。您会看到 JVM 输入的 main
方法只是通过将其结果传递给 performUnsafe
来调用 $main
(对应于您的 Frege main
函数)。没有别的办法了。
还有一个说法:有一个广为流传的误解,即 Haskell(或 Frege)类型为 IO
的函数是不纯的。你在这里看到这是完全错误的。您可以根据需要随时调用 IO
函数,除了构造 IO
操作外,什么都不会发生。这是绝对纯净的。对于相同的参数,您将得到 "same"(就行为而言,因为我们无法比较它们)IO
操作返回,并且不会发生副作用 until这样的动作是实际执行的。
但是,您会问,为什么 callingMain1
函数中的 performUnsafe
什么都不做?这是因为 return
是懒惰的。根本没有理由评估它的论点。这也表明 performUnsafe
在 Frege 代码中确实是不安全的,并且关于何时以及以何种顺序对其进行评估的所有赌注都不成立。再举个例子,试试:
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
不像 s
那样多态。
幸运的是,你也不能在 Java 中使用它作弊,因为 Func<RealWorld,Short>
不是 Func<Object,Short>
的子类型
最后,我想重申一下:运行一个来自Java的IO action,除了传给performUnsafe
,没有别的办法
希望对您有所帮助,有什么不明白的可以随时提问。
首先对我的英语感到抱歉,而且我正在努力学习 Haskell
我会 运行 从 java 调用 Frege 代码 (Haskell),几乎所有 我设法按照找到的说明使其全部工作 在各种网站上......但我仍然对以下代码有疑问, 对请求的冗长感到抱歉...
javaHelloTest.java
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("========================");
}
}
fregeHelloTest.fr
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) ) )
fregeHelloTest.java(从 fregec 生成)
{ ... omissis ... }
final public class FregeHelloTest {
final public static Func.U<RealWorld, Short> $main(final Lazy<PreludeBase.TList<String/*<Character>*/>> arg) {
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>*/> η11) {
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, η11.call());
}
}
);
}
},
Thunk.<String/*<Character>*/>lazy("Hello World from Frege code ...")
).call();
}
final public static short callingMain2(final Lazy<PreludeBase.TList<String/*<Character>*/>> arg) {
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));
}
}
)
)
).call();
}
final public static Func.U<RealWorld, Short> callingMain1(final Lazy<PreludeBase.TList<String/*<Character>*/>> arg) {
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));
}
}
)
);
}
final public static short callingMain0(final Lazy<PreludeBase.TList<String/*<Character>*/>> arg) {
return (short)PreludeBase.TST.<Short>performUnsafe(FregeHelloTest.$main(arg)).call();
}
public static void main(final java.lang.String[] argv) { ... omissis ... }
}
程序输出...入口点:local.java.JavaHelloTtest.main
------------------
Hello World from Java code ...
========================
callingMain0 ...
------------------------
Hello World from Frege code ...
========================
callingMain1 ...
------------------------
========================
callingMain2 ...
------------------------
Hello World from Frege code ...
========================
经过长时间的(对我而言)调查,我意识到这是正确的
"CallingMain1" 不执行任何操作...事实上,如您所见
由 "callingMain2" 生成需要 "run" ... 但如果我尝试
使用 "run" 执行,返回 "callingMain1" IDE
(Eclipse 然后是编译器)告诉我签名不正确,
PreludeBase.TST.
显然(我认为)"callingMain1" 的签名(Haskell)是正确的... 而且我认为没有人可以触摸...
现在的问题......在这一点上我认为,也许应该是 一个功能... TST.runOnRealWorld 允许评估 IO() 还从"callingMain1" 返回;然而,就像这一代人一样 of "callingMain2" 我清楚地看到操作被改变了 即时 "Object" 我不得不假设这个函数不存在...
这是想要的或者只需要添加一个"run"方法 允许 java 评估 "callingMain1" ?
的输出或者,更有可能的是,我了解得很少......提前致谢......
首先,我想说没有必要为努力学习而感到遗憾Haskell。从相反的方面来说。认为自己属于精英,insead!
为 callingMain0
生成的 java 代码是 运行 来自 Java 的 I/O 操作的正确代码。我建议直接使用它(或通过 Java 实用方法),出于卫生原因,不要像 callingMain0
这样看似纯粹的辅助函数。
顺便说一句,当你传递一个具有 Frege 代数数据类型的值(枚举除外)时,你不需要将它包装在额外的 Thunk.<...>lazy()
中,因为所有这些类型都已经实现了 Lazy
界面。所以你可以这样写:
FregeHelloTest.callingMain0(PreludeArrays.IListSource_JArray.<String>toList(args));
无论函数实际需要惰性列表还是严格列表,这都有效。
接下来,callingMain1
当然,它什么都不做,就像
FregeHelloTest.$main(...)
什么都不做。为什么?因为类型是 IO ()
这种类型告诉我们函数 returns 一个动作,当该动作被执行时将产生一个 ()
。而在 Frege 中 only 执行 IO 动作的方式是通过 PreludeBase.TST.<T>performUnsafe
。但是您没有将操作(即调用 callingMain1(...)
的结果)传递给 performUnsafe
。因此,该操作永远不会执行。
备注:当您检查为您的 Frege 模块生成的代码时,您可能已经注意到 main
方法的存在。如果没有,请查找。您会看到 JVM 输入的 main
方法只是通过将其结果传递给 performUnsafe
来调用 $main
(对应于您的 Frege main
函数)。没有别的办法了。
还有一个说法:有一个广为流传的误解,即 Haskell(或 Frege)类型为 IO
的函数是不纯的。你在这里看到这是完全错误的。您可以根据需要随时调用 IO
函数,除了构造 IO
操作外,什么都不会发生。这是绝对纯净的。对于相同的参数,您将得到 "same"(就行为而言,因为我们无法比较它们)IO
操作返回,并且不会发生副作用 until这样的动作是实际执行的。
但是,您会问,为什么 callingMain1
函数中的 performUnsafe
什么都不做?这是因为 return
是懒惰的。根本没有理由评估它的论点。这也表明 performUnsafe
在 Frege 代码中确实是不安全的,并且关于何时以及以何种顺序对其进行评估的所有赌注都不成立。再举个例子,试试:
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
不像 s
那样多态。
幸运的是,你也不能在 Java 中使用它作弊,因为 Func<RealWorld,Short>
不是 Func<Object,Short>
最后,我想重申一下:运行一个来自Java的IO action,除了传给performUnsafe
希望对您有所帮助,有什么不明白的可以随时提问。