我的弗雷格代码如下(主要是注意getDatabase的类型签名)
module fregeHelper.FregeCode where
--Java's String.split method
pure native split :: String -> String -> JArray String
--Java's ArrayList<t>
data ArrayList t =native java.util.ArrayList where
native new :: () -> STMutable s (ArrayList t)
native add::Mutable s (ArrayList t)-> t -> ST s ()
getDatabase::String->(IO (STMutable s (ArrayList (String, String))))
getDatabase s = do
fileContents <- readFile s
let processedData = map ((\x->(elemAt x 0, elemAt x 1)) . (flip split ";")) . lines $ fileContents
return $ fold foldAdd (ArrayList.new ()) processedData
where
foldAdd::ST s (Mutable s (ArrayList t)) -> t -> ST s (Mutable s (ArrayList t))
foldAdd list elem = list >>= \x->(ArrayList.add x elem >> return x)
然后从Java我想定义以下函数(其中DATABASE是一个字符串常量):
private void readDatabase() {
myList = Delayed.<ArrayList<TTuple2>>forced(
fregeHelper.FregeCode.getDatabase(DATABASE));
}
然而,这给了我一个java.lang.ClassCastException: frege.prelude.PreludeBase$TST$1 cannot be cast to java.util.ArrayList
通过实验,我不得不将代码更改为
private void readDatabase() {
fighters = Delayed.<ArrayList<TTuple2>>forced(
fregeHelper.FregeCode.getDatabase(DATABASE)
.apply(null)
.apply(null)
);
}
我在后者中添加了 null 只是为了表明我传入的内容并不重要。我不知道为什么我必须应用该函数三次(我不能立即强制评估)。有什么办法可以删除应用程序或对为什么它们是必要的有一些合理化?(注意:使用 .result() 无济于事。)