# Can anyone explain these basic partial application issues?

**URL:** <https://forums.fsharp.org/t/can-anyone-explain-these-basic-partial-application-issues/2426>\
**Category:** General\
**Tags:** beginners\
**Created:** [October 5, 2022, 11:38am UTC](https://forums.fsharp.org/t/can-anyone-explain-these-basic-partial-application-issues/2426 "2022-10-05T11:38:40Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![GarryP](https://avatars.discourse-cdn.com/v4/letter/g/da6949/32.png) [@GarryP](https://forums.fsharp.org/u/GarryP)\
**Post date:** [October 5, 2022, 11:38am UTC](https://forums.fsharp.org/t/can-anyone-explain-these-basic-partial-application-issues/2426/1 "2022-10-05T11:38:40Z")

</div>

I have some very basic code which works:

```auto
let randomNumberGenerator = System.Random.Shared

let randomFraction = (fun () -> randomNumberGenerator.NextDouble())

let shuffle (randomNumber : unit -> float) (data: 'a list) = data |> List.sortBy (fun _ -> randomNumber())

let shuffler data = shuffle randomFraction data

[1; 2; 3; 4; 5; 6] |> shuffler

```

If I remove the ‘data’ parameter from the end of the shuffler function definition, e.g. `let shuffler data = shuffle randomFraction` – I don’t get a compiler error but I get this when I run the code via the FSI:

> Scratchpad3.fsx(14,1): error FS0030: Value restriction. The value ‘it’ has been inferred to have generic type  
> val it: ('\_a list → '\_a list)  
> Either make the arguments to ‘it’ explicit or, if you do not intend for it to be generic, add a type annotation.

If I then remove the ‘data’ from the shuffler parameters, e.g. `let shuffler = shuffle randomFraction` - the code works again.

However, if I then comment out the last line, where the shuffler function is being used, I get a compiler error:

> Severity Code Description Project File Line Suppression State  
> Error FS0030 Value restriction. The value ‘shuffler’ has been inferred to have generic type  
> val shuffler: ('\_a list → '\_a list)  
> Either make the arguments to ‘shuffler’ explicit or, if you do not intend for it to be generic, add a type annotation. F# Miscellaneous Files \Scratchpad3.fsx 12 Active

This seems odd to me but should I be expecting it?

There’s probably a perfectly reasonable explanation but I don’t understand why the shuffler function should become ‘invalid’ when it’s not being ‘used’.

---

<div class="post-metadata">

**Author:** ![Prash](https://yyz2.discourse-cdn.com/flex030/user_avatar/forums.fsharp.org/prash/32/815_2.png) [@Prash](https://forums.fsharp.org/u/Prash)\
**Post date:** [October 6, 2022, 9:35am UTC](https://forums.fsharp.org/t/can-anyone-explain-these-basic-partial-application-issues/2426/2 "2022-10-06T09:35:57Z")

</div>

A function can be generic, but a “plain value” can’t. `let shuffler = shuffle randomFraction` is a plain value because it doesn’t have a function parameter written out. This is true even though the value is ultimately a function! I believe it’s a limitation of the .NET type system that F# wants to remain compatible with.

So when the `shuffler` value is actually used on an `int list` then the compiler can infer the generic type argument to be `int` and make `shuffler` concrete, not generic. When the usage is removed, it doesn’t have a way to infer the type argument, and it can’t store a generic value, and so there’s a compiler error.

Another option you have is to add an explicity type argument to `shuffle`:

```nohighlight
let shuffle<'a> (randomNumber : unit -> float) (data: 'a list) = data |> List.sortBy (fun _ -> randomNumber())

let shuffler<'a> = shuffle<'a> randomFraction

```

This means explictly passing the argument all the way through to the `shuffle` function as well. Now `shuffler` is actually more of a function than a value because it doesn’t run until a type argument is provided. Here it is still generic, and doesn’t need to be called at all.

That was my attempt to explain it! Hope that it helps. More info can be found in these links:

> **[Automatic Generalization - F#](https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/generics/automatic-generalization#value-restriction)**
>
> Learn how F# automatically generalizes the arguments and types of functions so that they work with multiple types when possible.

> <https://stackoverflow.com/questions/1131456/understanding-f-value-restriction-errors>

---

<div class="post-metadata">

**Author:** ![GarryP](https://avatars.discourse-cdn.com/v4/letter/g/da6949/32.png) [@GarryP](https://forums.fsharp.org/u/GarryP)\
**Post date:** [October 6, 2022, 1:52pm UTC](https://forums.fsharp.org/t/can-anyone-explain-these-basic-partial-application-issues/2426/3 "2022-10-06T13:52:21Z")

</div>

Thanks for that explanation.

Might take me a while to get it to ‘sink in’.
