1

我正在尝试使用frege.java.Util模块来构造一个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。我该如何解决这种歧义?

4

1 回答 1

1

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

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

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

但是,当您经常需要一个空的属性列表时,以下会更好:

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

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

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

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

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

于 2015-03-14T12:44:31.187 回答