如何在Android上运行Frege程序?

我对函数式语言的Android编程很感兴趣,最好是接近Haskell。 弗雷格似乎是一个不错的选择。 我发现有人已经做过这样的概念validation应用程序 ,但我找不到它的来源或任何类似的东西。

所以我的问题是,如何在Android上运行Frege程序,它有多难以及最终的障碍是什么?

Solutions Collecting From Web of "如何在Android上运行Frege程序?"

我看到的主要障碍是,目前无法将frege源编译为实现某个接口或扩展另一个类的java类。

相反,从frege模块生成的java类只是静态方法和您定义的其他东西的命名空间。

因此,要制作一个简单的Android项目,从frege调用java是不够的,这很容易,但也可以从java调用frege。 换句话说,你需要字面意义上的完整* inter *可操作性。

当然,它可以这样做,但必须说代码生成并不是为了方便java使用而设计的。

我还没有完成Android项目,因此我不确定需要多少胶水代码。

最后一个警告:Gabriel Riba先前的工作是使用早期版本的编译器完成的。 甚至还有支持JDK6的frege发行版的链接 – 请不要使用它,它与更新的版本不兼容。

如果你愿意接受它,你将通过上面提到的谷歌小组获得所有可能的支持。 如果有人制作并记录了一些“规范”的方法来实现这一点,那就太棒了。

我不熟悉frege,我没有尝试在Android上使用scala或其他JVM语言。

话虽这么说,如果我尝试类似的东西,这些是我可能会采取的步骤,试图找出如何让它工作。

  1. 在frege中构建一个基于命令行的HelloWorldtypes应用程序,可以运行,例如java -jar HelloWorld.jar HelloWorld

  2. 在HelloWorld.jar上运行dx,然后尝试使用dalvikvm从adb shell获取Android设备上的示例。 即dalvikvm -cp blah.dex HelloWorld

  3. 弄清楚如何从frege中的Android sdk提供的android.jar中引用/使用类

  4. 在frege中构建一个简单的概念certificateActivity类,并从中手动构建一个classes.dex文件

  5. 在java中构建类似的概念validation应用程序,并使用现有的android工具构建apk

  6. 替换apk中的classes.dex,重新签名apk,看看它是否有效

  7. 如果你有那么多工作,那么从那里,你可以为frege工作更好的构建故事,使用aapt编译资源,并最终从头开始构建一个完整的apk。

从我可以通过快速网络搜索中收集的所有信息,包括来自frege – 编程语言邮件列表的一些命中,它看起来不像只有Frege的Android应用程序。

相反,您必须使用其他一些支持Android的语言并使用它来调用您的Frege代码。 生成这样的“存根”可能会自动完成,但我没有看到现有的工具。

围绕由Frege和Android的Java编译器生成的Java代码也存在问题,但这似乎是使用反向转译工具相对容易解决的问题。

https://groups.google.com/forum/#!topic/frege-programming-language/Ounzmu-oHJQ https://groups.google.com/forum/#!topic/frege-programming-language/8bkWorojiiY

我还希望有一种参考多态性和ad-hoc多态性可用于Android开发的引用透明,强types语言。 虽然缺少这一点,但我建议使用Scala进行Android开发。

如果你想在弗雷格完​​全写你的应用程序,那将更加棘手。 您需要为Android API编写包装器,因为FregeAndroid包装器似乎缺少某些文件 。

但是,如果你想用Java编写你的UI,并为你的应用程序逻辑调用Frege,我有一个示例项目 ,它展示了如何做到这一点。

我的示例项目在Frege中有这个function:

extraText :: String -> String extraText who = "\nHello, " ++ who ++ "!" 

然后我从Java调用:

 public class FregeActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); TextView textView = (TextView) findViewById(R.id.txt); textView.append(FregeCode.extraText("Android")); } } 

看起来像这样

FregeActivity

我的示例项目使用Frege 3.23,因此您可以使用从Java调用Frege的旧方法 。 我没有尝试过使用Frege 3.24,但是如果你想尝试一下,你会使用新方法 。

唯一真正棘手的部分是获得一个构建Frege代码的build.gradle 。 我开始使用AndreasLändle在Frege邮件列表上发布的片段 ,然后我将其充实到一个完整的build.gradle中 。 我无法让Proguard工作,因此生成的APK包含整个frege.jar 。 这有点膨胀应用程序,它需要打开Multidex ,但否则它似乎很好。

另外,请注意我的示例项目需要API Level 21或更高版本,因为Frege需要ForkJoinPool ,而Android只有21级及以上版本。

对于任何仍然感兴趣的人,我在这里有一篇关于它的博客文章。 您必须设置gradle构建以将Frege代码编译为java并将其放入java源路径中。 然后你必须子类化活动并定义一些自定义包装器

 data Bundle = native android.os.Bundle data Context = native android.content.Context data FregeActivity = native android.app.Activity where native getApplicationContext :: MutableIO FregeActivity -> IO (MutableIO Context) native setContentView :: MutableIO FregeActivity -> MutableIO TextView -> IO () data TextView = native android.widget.TextView where native new :: MutableIO Context -> STMutable RealWorld TextView native setText :: MutableIO TextView -> String -> IO () onCreateF :: MutableIO FregeActivity -> IO () onCreateF !this = do context < - this.getApplicationContext tv <- TextView.new context tv.setText "Hello, Android - Love, Frege" this.setContentView tv native module type FregeActivity where { @Override public void onCreate(android.os.Bundle savedInstanceState) { super.onCreate(savedInstanceState); final frege.run7.Func.U res = RunTM.>cast(onCreateF(this)).call(); frege.prelude.PreludeBase.TST.run(res).call(); } }