Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is F#'s type inference so fickle?

The F# compiler appears to perform type inference in a (fairly) strict top-to-bottom, left-to-right fashion. This means you must do things like put all definitions before their use, order of file compilation is significant, and you tend to need to rearrange stuff (via |> or what have you) to avoid having explicit type annotations.

How hard is it to make this more flexible, and is that planned for a future version of F#? Obviously it can be done, since Haskell (for example) has no such limitations with equally powerful inference. Is there anything inherently different about the design or ideology of F# that is causing this?

like image 230
J Cooper Avatar asked Jul 01 '10 23:07

J Cooper


People also ask

Why is F MA and not f MV?

F=MA is describing a force, while P=MV is actually momentum. The first equation states that a Force is equal to Mass times Acceleration, or Newton's second law of motion. The second one states that Momentum (P) is equal to Mass times Velocity. Objects that have momentum are not necessarily being acted on by a force.

What does F mean in physics?

F = force m = mass a = acceleration Newton's Second Law.

Why is F MA so important?

If you can measure the mass of your object and how it's accelerating, you can use F = ma to determine the net force acting on the object. If you can measure the mass of your object and you know (or can measure) the net force being applied to it, you can determine how that object will accelerate.


1 Answers

Is there anything inherently different about the design or ideology of F# that is causing this?

Yes. F# uses nominal rather than structural typing because it is simpler and, therefore, easier for mere mortals to use.

Consider this F# example:

let lengths (xss: _ [] []) = Array.map (fun xs -> xs.Length) xss  let lengths (xss: _ [] []) = xss |> Array.map (fun xs -> xs.Length) 

The former does not compile because the type of xs inside the anonymous function cannot be inferred because F# cannot express the type "some class with a Length member".

In contrast, OCaml can express the direct equivalent:

let lengths xss = Array.map (fun xs -> xs#length) xss 

because OCaml can express that type (it is written <length: 'a ..>). Note that this requires more powerful type inference than either F# or Haskell currently have, e.g. OCaml can infer sum types.

However, this feature is known to be a usability issue. For example, if you screw up elsewhere in the code then the compiler has not yet inferred that the type of xs was supposed to be an array so any error message it can give can only provide information like "some type with a Length member" and not "an array". With only slightly more complicated code, this quickly gets out of control as you have massive types with many structurally inferred members that don't quite unify, leading to incomprehensible (C++/STL-like) error messages.

like image 78
J D Avatar answered Sep 29 '22 06:09

J D