Search code examples
javafrege

How to map Java overloaded constructors to Frege functions


Java (unfortunately) supports constructors and methods overload. For example, the HashMap has four constructors. In Frege I can't do:

data Map = native java.util.Map

data HashMap = native java.util.HashMap where
    native new :: () -> STMutable s HashMap
    native new :: Int -> STMutable s HashMap
    native new :: Int -> Float -> STMutable s HashMap
    native new :: Mutable s Map -> STMutable s HashMap

This doesn't compile because I can't bind four times "new". Is it possible to have four "Java constructors" in a Frege datatype?


Solution

  • Overloaded constructors and methods can be defined using |:

    data HashMap k v = native java.util.HashMap where
    
      native new :: Mutable s (Map k v) -> STMutable s (HashMap k v)
                  | () -> STMutable s (HashMap k v)
                  | Int -> STMutable s (HashMap k v)
                  | Int -> Float -> STMutable s (HashMap k v)
    

    You can also use this https://github.com/Frege/native-gen as the starting point to generate Frege code from Java class. The above code is generated using that project.

    I said starting point because this cannot be completely automated. We can't determine the purity of a method and nulls from native methods. Hence you can take the generated code and modify the purity or make the return type Maybe a if you know that the method may return null.