【问题标题】:How to run Frege programs on Android?如何在 Android 上运行 Frege 程序?
【发布时间】:2013-06-17 19:49:21
【问题描述】:

我对用函数式语言为 Android 编程很感兴趣,最好是接近 Haskell。 Frege 似乎是个不错的选择。我发现有人已经做了这样的proof-of-concept application,但我找不到它的来源或类似的东西。

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

【问题讨论】:

标签: android haskell dalvik frege


【解决方案1】:

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

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

因此,要制作一个不简单的Android项目,从frege调用java是不够的,这很容易,而且从java调用frege也是如此。换句话说,您需要完全的*互*操作性。

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

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

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

如果您仍然愿意接受,您将通过上述 google 小组获得一切可能的支持。如果有人制定并记录了一些“规范”的方式来实现这一点,那就太好了。

【讨论】:

【解决方案2】:

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

话虽如此,如果我要尝试这样的事情,我可能会采取这些步骤来尝试弄清楚如何让它发挥作用。

  1. 在 frege 中构建一个简单的基于命令行的 HelloWorld 类型应用程序,可以运行,例如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 中构建一个简单的概念证明 Activity 类,并从中手动构建 classes.dex 文件

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

  6. 替换apk中的classes.dex,退出apk,看看是否有效

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

    李>

【讨论】:

  • 如果您确实想在 Android 上试用 Scala,请使用 Scala-IDE;它有在 Android 上执行 Scala 的特定文档。
【解决方案3】:

如果您想完全在 Frege 中编写您的应用程序,那将更加棘手。您需要为 Android API 编写包装器,因为 FregeAndroid wrapper 似乎是 missing some files

但是,如果您想用 Java 编写您的 UI,并为您的应用程序逻辑调用 Frege,我有一个 sample project,它显示了如何做到这一点。

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

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"));
    }
}

看起来像这样

我的示例项目使用 Frege 3.23,因此您可以使用 old way of calling Frege from Java。我没有尝试过使用 Frege 3.24,但如果你想尝试,你会使用 the new way

唯一真正棘手的部分是获得一个build.gradle 来构建弗雷格代码。我从 Frege 邮件列表中的 snippet posted by Andreas Ländle 开始,然后将其充实为 a complete build.gradle。我无法让 Proguard 工作,因此生成的 APK 包含整个 frege.jar。这让应用有点膨胀,需要打开Multidex,但其他方面似乎还不错。

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

【讨论】:

    【解决方案4】:

    根据我从快速网络搜索中收集到的所有信息,包括来自 frege--programming-language 邮件列表的一些点击,看来只有 Frege 的 Android 应用程序是不可能的。

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

    Frege 生成的 Java 代码和 Android 的 Java 编译器也存在一些问题,但这似乎是使用逆向翻译工具相对容易解决的问题。

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

    我还希望有一种引用透明、强类型的语言,它同时具有参数多态性和临时多态性,可用于进行 Android 开发。虽然缺少这一点,但我推荐使用 Scala 进行 Android 开发。

    【讨论】:

    • 只是为了记录,Scala 既有参数多态性,也有今天可用的临时多态性,就像 Haskell/Frege 一样,尽管语法不太好。
    • Scala 不是引用透明的,+Erik Allik。除此之外,它符合我的标准,即使是“古怪的”临时多态性。 (老实说,Haskell 的类型类系统不错,但也有点不靠谱。)
    • 您的意思是没有强制引用透明度。是的,我希望我主要有 Scala 类型类语义,主要是 Haskell 的语法,这是我认为 Haskell 的发展方向。
    • 无需使用“强制”限定符。如果语言中的表达式不具有引用透明性,则该语言不具有引用透明性。 (例如,Scala。)
    【解决方案5】:

    对于仍然感兴趣的人,我有一篇关于它的博客文章here。您必须设置您的 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<Object,Short> res = RunTM.<frege.run7.Func.U<Object,Short>>cast(onCreateF(this)).call();
            frege.prelude.PreludeBase.TST.run(res).call();
        }
    }
    

    【讨论】:

    • 链接失效了,你能查一下吗?
    • 我会把它放回去。这是一个更新且有用的贡献:github.com/mchav/froid
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多