Are F# module signature files mostly useless, unlike OCaml, because F# doesn't have functors?
What are use cases for F# module signature files?
A use case is a methodology used in system analysis to identify, clarify and organize system requirements. The use case is made up of a set of possible sequences of interactions between systems and users in a particular environment and related to a particular goal.
There are basically two types of use cases analysts can draw from: Business Use Cases and System Use Cases. Business Use Cases are more about what a user expects from a system while System Use Cases are more about what the system does. Both use case types can be represented by diagrams or text.
There are four basic types of behavioral relationships: communicates, includes, extends, and generalizes.
A use case describes how actors uses a system to accomplish a particular goal. Use cases are typically initiated by a user to fulfill goals describing the activities and variants involved in attaining the goal. Relationship. The relationships between and among the actors and the use cases.
Clarification for future readers: this answer was written for the original question, before it was updated. The original question was:
Are F# signatures mostly useless, unlike OCaml, because F# doesn't have functors?
What are use cases for F# signatures?
Though F# doesn't have OCaml modules and functors, it does have interfaces and objects, which provide similar, though a bit more limited functionality. These do require type signatures, because type inference doesn't work on them. For example:
type MyIntf =
abstract member m : sting -> int
let f i = i.m "hello"
// ^ error: cannot lookup member "m" on object "i" of indeterminate type
Notice that I've already needed a type annotation just to define the interface, since there is no other source of type information in the absence of an implementation for member m
. But even besides that, the usage of my interface also doesn't work without an explicit type.
While it's not clear that inferring types for objects and interfaces is actually impossible, F# just doesn't attempt to do it. The official F# policy is, as long as you're purely functional, you get HM type interference, but as soon as you get into objects and members, you're on your own, the compiler won't help you.
To make the above function f
work, I have to annotate the type of the i
parameter:
let f (i : MyIntf) = i.m "hello" // works now
Besides this technical requirement, type annotations are, of course, immensely valuable as documentation (which is guaranteed to not go out of sync), as well as barriers for runaway type inference.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With