Sdílet prostřednictvím


Automatické generalizace (F#)

F# používá odvození typu vyhodnotit typy funkcí a výrazy.Toto téma popisuje, jak F# automaticky zobecňuje argumenty a typy funkcí tak, že pracují s více typy, pokud je to možné.

Automatické generalizace

F# kompilátoru, když provádí odvození typu funkce, určuje zda daný parametr může být obecné.Kompilátor zkoumá každý parametr a určuje, zda má funkce závislé na konkrétním typu parametru.Pokud ne, je typ odvodit být obecný.

Následující příklad kódu ukazuje funkci, která kompilátor odvodí být obecný.

let max a b = if a > b then a else b

Typ je odvodit se 'a -> 'a -> 'a.

Typ označuje, zda je funkce, která používá dva argumenty stejné Neznámý typ a vrátí hodnotu stejného typu.Z důvodů, které mohou být předchozí funkce obecného je, že větší-než operátor (>) je obecný.Vyšší-než podpis má operátor 'a -> 'a -> bool.Všechny operátory jsou obecné a pokud kód funkce používá parametr typu s Obecné funkce nebo operátor, parametr typu nelze Všeobecné.

Protože max je obecný, ji lze použít s typy jako int, float, a tak dále, jak je uvedeno v následujících příkladech.

let biggestFloat = max 2.0 3.0
let biggestInt = max 2 3

Dva argumenty však musí být stejného typu.Podpis je 'a -> 'a -> 'a, není 'a -> 'b -> 'a.Proto následující kód vytvoří chybu, protože typy neodpovídají.

// Error: type mismatch.
let biggestIntFloat = max 2.0 3

max Funkce pracuje rovněž typu, který podporuje vyšší-než operátor.Proto můžete také použít ji v řetězci, jak je znázorněno v následujícím kódu.

let testString = max "cab" "cat"

Omezení hodnoty

Kompilátor provádí automatické generalizace pouze definice kompletní funkce, které obsahují explicitní argumenty a jednoduché nezměnitelné hodnoty.

To znamená, kompilátor Pokud chcete kompilovat kód, který není dostatečně omezen na určitý typ, ale není generalizovatelný problémy s chybu.Chybovou zprávu pro tento problém se týká toto omezení na automatické generalizace pro hodnoty jako hodnotu omezení.

Hodnota omezení chybě obvykle dochází, když chcete konstrukce být obecný, ale kompilátor nemá dostatečné informace k jeho generalize nebo Pokud vynecháte neúmyslně dostatečné informace o typu neobecné konstrukce.Řešení chyby hodnota omezení je poskytnout podrobnější informace podrobněji omezit problém odvození typu, jedním z následujících způsobů:

  • Omezíte typ na neobecné přidáním anotaci typu explicitní hodnoty nebo parametr.

  • Pokud problém pomocí nongeneralizable konstrukci definovat obecné funkce, jako je například funkce složení nebo nedokonale použity argumenty funkce curried, zkuste přepsat funkci jako definici běžné funkce.

  • Pokud je výraz, který je příliš složitý a být všeobecné, proveďte do funkce přidáním parametrem extra, nepoužité problém.

  • Přidejte explicitní obecný typ parametrů.Tato možnost se používá zřídka.

  • Následující kód příklady ilustrují každého z těchto scénářů.

Případ 1: Příliš složitý výraz.V tomto příkladu seznamu counter se int option ref, ale není definován jako jednoduché nezměnitelné hodnoty.

let counter = ref None
// Adding a type annotation fixes the problem:
let counter : int option ref = ref None

Případ 2: Použití nongeneralizable konstrukci definovat obecné funkce.V tomto příkladu konstruktu je nongeneralizable, neboť zahrnuje částečné uplatnění argumenty funkce.

let maxhash = max << hash
// The following is acceptable because the argument for maxhash is explicit:
let maxhash obj = (max << hash) obj

Případ 3: Přidání parametrem extra, nepoužité.Protože tento výraz není dostatečně jednoduchý pro generalizace, kompilátor problémy chybovou hodnotu omezení.

let emptyList10 = Array.create 10 []
// Adding an extra (unused) parameter makes it a function, which is generalizable.
let emptyList10 () = Array.create 10 []

Případ 4: Přidání parametrů typu.

let arrayOf10Lists = Array.create 10 []
// Adding a type parameter and type annotation lets you write a generic value.
let arrayOf10Lists<'T> = Array.create 10 ([]:'T list)

V posledním případě se změní hodnota typu funkce, které mohou být použity k vytvoření hodnoty mnoho různých typů, například takto:

let intLists = arrayOf10Lists<int>
let floatLists = arrayOf10Lists<float>

Viz také

Referenční dokumentace

Odvození typu (F#)

Generics (F#)

Staticky vyřešen parametry typu (F#)

Omezení (F#)