1. 程式人生 > 實用技巧 >F# 的語法與基本特性

F# 的語法與基本特性

本文只是筆記/摘錄,沒有解釋說明,因為原文有些句子太精彩了,忍不住要記下來。

原文:
https://fsharpforfunandprofit.com/posts/expressions-vs-statements/
https://fsharpforfunandprofit.com/series/understanding-fsharp-types.html

下面是摘錄:

  • In F# everything is an expression.
  • Using expressions consistently leads to code that is both safer and more compact.
  • In fact, it is not even helpful to think of “control flow” in a functional language; the concept doesn’t really exist.
  • Better to just think of the program as a giant expression containing sub-expressions.
  • If you need to work with a disposable “outside” the function that created it, probably the best way is to use a callback.
  • One trick in F# is to appropriate the use keyword to do any kind of “stop” or “revert” functionality automatically.
  • It is considered a good practice to always have an explicit “do”, as it acts as documentation that you do not want a result.
  • The best way to avoid if-then-else is to use “match” instead.
  • The best way to avoid loops is to use the built in list and sequence functions instead.
  • There is no equivalent of “break” and “continue” (this can generally done better using sequences anyway).
  • In the functional world, returning error codes (or rather error types) is generally preferred to throwing exceptions.
  • The match..with should be on a new line.
  • If you can’t have every case be explicit, you might try to document your boundary conditions as much as possible, and assert an runtime error for the wildcard case.
  • You can match on subtypes, using the :? operator
  • Partial active patterns have a return value that is an option type. (MSDN)
  • To be as specific as possible when defining the domain, typically by creating lots of very specific types.
  • Complicated logic is often a sign that you don’t quite understand the domain properly.
  • A well designed object-oriented program will have a strong focus on behavior rather than data. A well designed functional program, on the other hand, will have a strong focus on data types rather than behavior.
  • Tuples are perfect for small, temporary, lightweight structures.
  • If you just need a single property, you can use dot notation rather than pattern matching. (Records)
  • Note that in F#, unlike some other functional languages, two types with exactly the same structural definition are not the same type.
  • The case constructors for union types are normal functions, so you can use them anywhere a function is expected.
  • A convenient thing about single case union types is you can pattern match directly against a value without having to use a full match-with expression.
  • The option type has functions such as IsSome, IsNone and Value, don’t use them! Instead use the Option module and the defaultArg function.
  • It is good practice to immediately check for nulls and convert them into an option type!
  • You can convert a primitive type to an object directly, by using the box keyword.
  • To convert an object back to an primitive type, use the unbox keyword.

The common naming conventions are as follows:

  • “a”, “b”, “c” etc., are types
  • “f”, “g”, “h” etc., are functions
  • “x”, “y”, “z” etc., are arguments to the functions
  • Lists are indicated by adding an “s” suffix, so that “xs” is a list of x’s, “fs” is a list of functions, and so on.

Formatted text using printf

https://fsharpforfunandprofit.com/posts/printf/

  • %s for strings
  • %b for bools
  • %i for ints
  • %f for floats
  • %A for pretty-printing tuples, records and union types
  • %O for other objects, using ToString()