Difference between `let f = fun a -> a-1` and `let f a = a-1` in F#

后端 未结 3 1672
北海茫月
北海茫月 2021-01-13 00:21

In F#, is there any difference whatsoever between let f = fun a -> a-1 and let f a = a-1? As far as I can see, the latter is simply syntactic s

3条回答
  •  南方客
    南方客 (楼主)
    2021-01-13 00:50

    The examples you provided are semantically the same, but the F# compiler has everything to do with it.

    Let's look at a different (generic) function:

    // val singleton1 : x:'a -> List<'a>
    let singleton1 x = [x]
    
    // val singleton2 : x:'a -> List<'a>
    let singleton2 = fun x -> [x]
    

    As you can see, the signatures are the same. But if you think about it, these two shouldn't really be the same: The first one is a true function (compiles to a .NET method), but the second one is simply a value holding a function (delegate or Func in C#). But there are no generic values in the .NET runtime. This only works because the F# compiler is smart enough to make singleton2 a function too.

    You can see what I mean here:

    let singleton3 = id >> fun x -> [x]
    

    Now here we outsmarted the F# compiler and this won't compile because of Value Restriction (scroll down to the topic), even though it should be semantically the same as singleton2.

    So, to sum up: From a semantic point of view, your definitions are the same, but because of restrictions in the .NET runtime, the F# compiler has to do some extra work to enable this.


    One other difference I just remembered is that only functions can be marked inline:

    let inline f a = a-1 // OK
    let inline f = fun a -> a-1 // Error
    

提交回复
热议问题