Rodzaj (teoria typów)
Rodzaj – w teorii typów, schemat konstruktora typu. System rodzajów jest najczęściej rachunkiem lambda z typami prostymi, wyposażonym w typ pierwotny, oznaczony jako i nazywany „typem”, który jest rodzajem dowolnego typu danych, który nie wymaga parametryzacji.
Ponieważ operatory typów wyższego rzędu są rzadko spotykane w językach programowania, w większości praktyk programistycznych rodzaje są używane do rozróżnienia typów danych od konstruktorów typów używanych do implementacji polimorfizmu parametrycznego. Rodzaje pojawiają się, jawnie lub niejawnie, w językach, których systemy typów oferują programiście swobodny dostęp do polimorfizmu parametrycznego, przykładowo jak C++, [1] Haskellu i Scali. [2]
Przykłady
[edytuj | edytuj kod]- , wymawiane jako „typ”, jest rodzajem wszystkich typów danych. Przykładami typów rodzaju są całkowitoliczbowe typy danych, logiczne typy danych, a w funkcyjnych językach programowania typy monomorficznych funkcji.
- jest rodzajem jednoargumentowego konstruktora typu, przykładem czego może być lista.
- jest rodzajem konstruktora typu o dwóch parametrach (przekazywanych poprzez currying), przykładowo pary lub typu funkcji (nie mylić z wynikiem jego aplikacji, który jest „gotowym” typem funkcji, a więc rodzaju ).
- jest rodzajem unarnego operatora wyższego rzędu parametryzowanego jednoargumentowymi konstruktorami typów.[3] Przykładem takiego operatora może być tablica mieszająca mapująca liczby na liczby parametryzowana typem kontenera („bucket”) użytego do rozwiązywania kolizji.
Rodzaje w Haskellu
[edytuj | edytuj kod](Uwaga : dokumentacja Haskella używa tej samej strzałki zarówno dla typów, jak i rodzajów funkcji.)
System rodzajów Haskella 98 [4] obejmuje dokładnie dwa rodzaje:
- , wymawiane "typ" to rodzaj wszystkich typów danych.
- jest rodzajem konstruktora typu, który przyjmuje typ rodzaju i produkuje rodzaj rodzaju .
Konstruktor typu przyjmuje jeden lub więcej argumentów by stworzyć końcowy typ danych.[5] [6] W ten sposób Haskell realizuje typy parametryczne. Przykładowo []
(lista) jest takim konstruktorem typu — by stać się pełnoprawnym typem potrzebuje jednego argumentu określającego typ elementów listy. Z tego powodu [Int]
(lista liczb całkowitych), [Float]
(lista liczb zmiennoprzecinkowych), a nawet [ [ Int ] ]
(lista list liczb całkowitych) są prawidłowymi aplikacjami konstruktora typu []
. Stąd można wywnioskować, że []
jest typem rodzaju . Ponieważ Int
ma rodzaj , aplikacja []
do niego daje [Int]
, rodzaju .
Rekonstrukcja rodzajów
[edytuj | edytuj kod]Standardowy Haskell nie dopuszcza rodzajów polimorficznych, mimo pełnego wsparcia typów polimorficznych. Stąd w poniższym przykładzie:
data Tree z = Leaf | Fork (Tree z) (Tree z)
teoretycznie rodzaj parametru z
może być dowolny, jednakże Haskell domyślnie zakłada, że parametry konstruktorów danych są opisywane przez typ rodzaju , chyba że deklaracja wprost wskazuje inaczej (patrz poniżej). Z tego powodu kompilator odrzuci następujące użycie Tree
:
type FunnyTree = Tree [] -- błąd
Konkretnie rzecz ujmując, rodzaj []
, czyli , nie pasuje do domyślnego rodzaju z
, czyli .
Operatory wyższych rzędów są w pełni akceptowane, jeśli tylko spełniają założenia kontroli rodzajów. Przykładowo:
data App unt z = Z (unt z)
ma rodzaj . To znaczy, że unt
jest jednoargumentowym konstruktorem typu, którego parametr jest zwykłym typem ().
Warto nadmienić, że GHC oferuje rozszerzenie PolyKinds
, które wraz z KindSignatures
wprowadza rodzaje polimorficzne. Na przykład, następujący kod przechodzi kontrolę typów i rodzajów:
data Tree (z :: k) = Leaf | Fork (Tree z) (Tree z)
type FunnyTree = Tree [] -- OK
Od wersji GHC 8.0.1 typy i rodzaje traktowane jak równoprawne koncepty. [7]
Zobacz też
[edytuj | edytuj kod]Przypisy
[edytuj | edytuj kod]- ↑ CS 115: Parametric Polymorphism: Template Functions. www2.cs.uregina.ca. [dostęp 2020-08-06].
- ↑ Generics of a Higher Kind
- ↑ Pierce (2002), chapter 32
- ↑ Kinds - The Haskell 98 Report
- ↑ Chapter 4 Declarations and Binding. Haskell 2010 Language Report. [dostęp 2012-07-23].
- ↑ Lipovača Miran: Learn You a Haskell for Great Good!. Making Our Own Types and Typeclasses. [dostęp 2012-07-23].
- ↑ 9.1. Language options — Glasgow Haskell Compiler Users Guide.