In F#, generic functions allow you to write code that works with any data type while maintaining full type safety. Unlike languages where you might use object and cast types, F# uses Automatic Generalization to infer the most generic version of your code possible.
1. Automatic Generalization
Most of the time, you don't even need to use special syntax. If the compiler can’t find a reason to restrict a type, it makes it generic automatically.
// F# infers this as: 'a -> 'a -> 'a * 'a
let swap a b = (b, a)
let result1 = swap 10 20 // Works with ints
let result2 = swap "Hello" "World" // Works with strings
In F#, generic type parameters are prefixed with a tick (e.g., 'a, 'T, 'Key).
2. Explicit Syntax
If you want to be explicit about your generics (useful for documentation or complex logic), you place the type parameters in angle brackets after the function name.
let printValue<'T> (value: 'T) =
printfn "The value is: %A" value
3. Generic Constraints
Sometimes you need a function to be generic, but only for types that support certain operations (like addition or comparison).
Common Constraints
| Constraint | Syntax | Description |
| Comparison | 'T : comparison | Allows use of >, <, =, etc. |
| Equality | 'T : equality | Allows use of = and <>. |
| Null | 'T : null | Type must support the null literal. |
| Inlining (Static) | inline | Used for math operators like + or -. |
Example: Comparison Constraint
let findMax<'T when 'T : comparison> (a: 'T) (b: 'T) =
if a > b then a else b
4. The inline Keyword (Statically Resolved Generics)
F# handles math differently. Because + is defined differently for int, float, and decimal, a standard generic function won't work for math unless you use inline.
// This works for any type that supports the + operator
let inline add x y = x + y
let sumInt = add 5 10 // 15
let sumFloat = add 5.5 1.2 // 6.7
Note: inline tells the compiler to replace the function call with the actual function body at the call site, allowing it to resolve the specific math operator needed.
5. Generic Type Definitions
Generics aren't limited to functions; they are the backbone of F# data structures.
type Result<'T> =
| Success of 'T
| Failure of string
let myNum = Success(42)
let myStr = Success("All good")
Summary Tips
- Let the compiler help: Start without type annotations; F# is remarkably good at generalizing for you.
- Check the Tooltip: Hover over your function name in your IDE. If you see 'a, it’s generic.
- Use inline for Math: If you get an error saying a type doesn't support +, inline is usually the fix.
'Programming' 카테고리의 다른 글
| haskell의 monad를 이해하기 쉽게 설명해. 예제도 포함하고 (0) | 2026.05.01 |
|---|---|
| java ee에서 value object의 public field로 컬럼들을 정의하고 사용하면 편한데 왜 private으로 하고 get, set 메소드를 만드는가 (0) | 2026.05.01 |
| java var declaration since when (0) | 2026.05.01 |
| java 1.8's new features (0) | 2026.04.23 |
| project euler 1 in java stream (0) | 2026.04.23 |