在弗雷格中使用 java.util.Properties

Use java.util.Properties in Frege

我正在尝试使用 frege.java.Util module 构建一个 Properties 实例。这是代码:

module frege_test.Application where

import frege.java.Util (Properties)

main :: [String] -> IO Int
main _ = do
  properties <- Properties.new ()
  return 0

那不编译,这里是编译错误:

E T:\Temp\frege-test\src\main\frege\Application.fr:7: overloaded  new  is ambiguos at type  ()→IO t17332
    It could mean one of
    Properties.newα  ::  ∀ s.() → STMutable s Properties
    Properties.newβ  ::  ∀ s.Mutable s Properties → STMutable s Properties
    Util.Hashtable.newα  ::  ∀ s k v.() → STMutable s (Util.Hashtable k v)
    Util.Hashtable.newβ  ::  ∀ s k v.Int → STMutable s (Util.Hashtable k v)
    Util.Hashtable.newγ  ::  ∀ s k v.Int → Float → STMutable s (Util.Hashtable k v)
    Util.Hashtable.newδ  ::  ∀ s k v.Mutable s (Util.Map k v) → STMutable s (Util.Hashtable k v)
frege_test.Application: build failed because of compilation errors.

怎么了?我什至没有导入 Util.Hashtable。我该如何解决这个歧义?

嗯,这是能够使用在 Java 中重载的方法的一些结果。虽然当重载具有相同的数量时,这在大多数情况下都没有任何问题,但在其他情况下,如果没有额外的类型注释,它并不总是有效。当没有关于变量 properties 应该是什么的其他可用信息时更是如此,如上例。

最简单的快速修复方法是 select 从错误消息中选择想要使用的重载类型并写入

properties <- (Properties.new :: () → STMutable s Properties) ()

然而,当你经常需要一个空的属性列表时,下面的会更好:

emptyProps :: ST s (Mutable s Properties)
emptyProps = Properties.new ()

这是有效的,因为类型注释为编译器提供了足够的信息来 select 正确的重载。你可以这样使用它:

main _ = do
    p <- emptyProps
    ...
    return 0

关于 Util.Hashtable:由于您导入了 frege.java.Util,因此那里定义的所有数据类型和函数都可用,并且可以使用限定名称访问,例如 Util.Hashtable

出于某种原因,编译器认为您可能需要这些。也许是因为它知道 java.util.Properties 是 java.util.Hastable.

的子类型