Void in constrast with Unit

前端 未结 2 1224
感动是毒
感动是毒 2020-12-20 17:09

I would like to understand which is the difference between these two programming concepts. The first represents the absence of data type and at the latter the type exists bu

相关标签:
2条回答
  • 2020-12-20 17:44

    The unit type just makes everything more regular. To an extent you can think of every function in F# as taking a single parameter and returning a single result. Functions that don't need any parameters actually take "unit" as a parameter, and functions that don't return any results return "unit" as a result. This has a variety of advantages; for one, consider how in C# you need both a slew of "Func" delegates to represent functions of various arities that return values, as well as a slew of "Action" delegates that do not return values (because e.g. Func<int,void> is not legal - void cannot be used that way, since it's not quite a 'real' type).

    See also F# function types: fun with tuples and currying

    0 讨论(0)
  • 2020-12-20 17:47

    In functional programming, we usually speak of mapping inputs to outputs. This literally means mapping an argument to its return value(s). But if something is going to be a function in the mathematical/category-theory sense, it has to return something. A void value represents that a function returns nothing, which is nonsensical in these terms.

    unit is the functional answer to void. It's essentially a type with only one value, (). It has a number of uses, but here's a simple one. Let's say you had something like this in a more traditional imperative language:

    public static <T, U> List<U> map(List<T> in, Function<T, U> func) {
      List<U> out = new ArrayList<U>(in.size());
      for (T t : in) {
         out.add(func.apply(t));
      }
      return out;
    }
    

    This applies a particular function func to every element on the list, producing a new list of func's output type. But what happens if you pass in a Function that just prints its arguments? It won't have an output type, so what can you put for U?

    In some languages, passing in such a function would break this code (like in C#, where you can't assign void to a generic type). You'd have to resort to workarounds like having an Action<T>, which can get clunky.

    This is where the concept of unit is useful: it is a type, but one that may only take on a single value. That greatly simplifies things like chaining and composition, and vastly reduces the number of special cases you have to worry about.

    0 讨论(0)
提交回复
热议问题