Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is RequireQualifiedAccess attribute?

Tags:

.net

f#

From the docs:

This attribute is used to indicate that references to the elements of a module, record or union type require explicit qualified access.

What is an explicit qualified access? What is an implicit access?

like image 434
MiP Avatar asked Jun 09 '17 16:06

MiP


3 Answers

Maybe a concrete example would help.

The List module has this attribute. This means you're not allowed to open the module:

open List // compile error!

map id [1;2]

Instead, you must do this:

List.map id [1;2]
like image 185
TheQuickBrownFox Avatar answered Nov 20 '22 01:11

TheQuickBrownFox


From The About F# Page

Adding the [<RequireQualifiedAccess>] attribute to a module indicates that the module may not be opened and that references to the elements of the module require explicit qualified access. For example, the Microsoft.FSharp.Collections.List module has this attribute.

This is useful when functions and values in the module have names that are likely to conflict with names in other modules and requiring qualified access can greatly increase the long-term maintainability and evolvability of a library: functions can be added to the module without breaking source compatibility.

like image 22
Eric Olsson Avatar answered Nov 20 '22 01:11

Eric Olsson


The operator behaviour of F# lists, arrays, and sequences is manually mirrored between modules so that you can work with these structures in a consistent way. The implementations are different.

if you'd prefer to work in an implicit style, it's easy to set this up. Like if you are working predominantly with Lists, you could do this:

let inline map = List.map

etc.

Perhaps in the future, the kind of module will be inferred from the context (ie. we're working with a list, so obviously map refers to List.map). Ultimately, this is a language design question. What should the sensible default be? Defaults always creep into the broader code bases. On average, is this default more useful to programmers? Hence the RequireQualifiedAccess flag. Someone decided that this was the sensible way to do it. What's idiomatic? Does this still make sense?

The documentation you quote is not strictly true. The below is all implicit (I don't need to use a fully qualified explicit DicriminatedUnion.Case1, for example):

type DiscriminatedUnion = 
  | Case1
  | Case2
  | Case3

let f x =
  match x with
  | Case1 -> "case1"
  | Case2 -> "case2"
  | Case3 -> "case3"

f Case1

Excerpt from the book Expert F#

Some functional languages, such as Haskell, allow you to implicitly pass dictionaries of operations through an extension to type inference known as type classes. At the time of writing, this isn’t supported by F#, but the designers of F# have stated that they expect a future version of the language to support this. Either way, explicitly passing dictionaries of operations is common in all functional programming and is an important technique to master.

like image 7
sgtz Avatar answered Nov 20 '22 01:11

sgtz