如何在Frege中的非纯本机函数中声明可变类型的可能?

时间:2015-08-19 13:32:27

标签: frege

native-gen工具为其生成本机声明 showOpenDialog中的javafx.stage.FileChooser方法就像这样

data FileChooser = mutable native javafx.stage.FileChooser where
 native showOpenDialog :: FileChooser -> Window -> IO File

编辑消息

Non pure native type File must be MutableIO
    File in IO actions.

现在设置

native showOpenDialog :: FileChooser -> Window -> MutableIO File

导致

FileChooser.showOpenDialog has an illegal
    return type for a method that is not pure, perhaps ST s (MutableIO
    File) would work

但是根据建议再次导致第一条错误消息。

编译器接受IOMutable File作为返回类型,这是有道理的 因为它是一个返回可变类型的IO动作。

如果可能,应调整编译器错误消息以避免用户端受挫。

但是,在这种特殊情况下,文件可以为null 核心类型不是File,而是Maybe File。 但是,仅使用IOMutable (Maybe File)会导致相当令人惊讶的消息

The type MutableIO (Maybe File) is illegal,
    Maybe File must be a native type.

有关如何正确声明此类型的任何建议吗?

1 个答案:

答案 0 :(得分:2)

native-gen生成的代码是错误的,因为File IOnative-genIO IOMutable,但文件实际上定义为有状态(不是{ {1}})本地类型,可以从declared看到。

type IOMutable d = IO (MutableIO d)定义为MutableIO d。 对于您的情况,可变的本机类型(data FileChooser = mutable native javafx.stage.FileChooser where native showOpenDialog :: FileChooser -> Window -> IO (Maybe (MutableIO File)) )可以为null,因此以下内容应该有效:

import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.Cursor;
import android.content.Context;
import android.content.ContentValues;


public class MyDBHandler extends SQLiteOpenHelper{

    private static final int DATABASE_VERSION = 1;
    private static final String DATABASE_NAME = "products.db";
    public static final String TABLE_PRODUCTS = "products";
    public static final String COLUMN_ID ="_id";
    public static final String COLUMN_PRODUCTNAME ="productname";


    public MyDBHandler(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, DATABASE_NAME, factory, DATABASE_VERSION);
    }


    @Override
    public void onCreate(SQLiteDatabase db) {


        String query= "CREATE TABLE " + TABLE_PRODUCTS + "(" +
                COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT , " +
                COLUMN_PRODUCTNAME + " TEXT " +
                ");";
        db.execSQL(query);


    }



    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_PRODUCTS);
        onCreate(db);
    }

    //add a new row to the database
    public void addProduct(products product)
    {
        final ContentValues values = new ContentValues();
        values.put(COLUMN_PRODUCTNAME, product.get_productname());

        SQLiteDatabase db= getWritableDatabase();
                db.insert(TABLE_PRODUCTS, null, values);
                db.close();





    }

    //delete product from the database
    public void deleteProduct(final String productname)
    {



                SQLiteDatabase db = getWritableDatabase();
        db.execSQL("DELETE FROM " + TABLE_PRODUCTS + " WHERE " + COLUMN_PRODUCTNAME + " =\"" + productname + "\";");





    }

    //printing out the database as a string

    public String databaseToString()
    {
        String dbString ="";
        SQLiteDatabase db= getWritableDatabase();
        String query = "SELECT * FROM "+ TABLE_PRODUCTS + " WHERE 1";

        //CURSOR POINTS TO A LOCATION IN THE DATABASE RESULTS
        Cursor c= db.rawQuery(query,null);
        //go to 1st row in your results
        c.moveToFirst();

        while(!c.isAfterLast())
        {
            if(c.getString(c.getColumnIndex("productname"))!=null)
            {
                dbString += c.getString(c.getColumnIndex("productname"));
                dbString += "\n";

            }
            c.moveToNext();