Salut Freeza,
Ce que entwanne a dit est correct. Juste pour rappel, la signature d’une fonction comporte 3 éléments: nom :: contexte => type
. Le contexte (ou les contraintes) donne des informations sur les types présents dans la signature. Ici on apprend donc que t
doit obligatoirement appartenir à la classe de type Foldable
. Foldable représente des structures de données sur lesquelles on peut itérer (c’est-à-dire utiliser la famille de fonctions fold*), comme par exemple les listes ou bien les arbres. Si tu es débutant en Haskell je te conseillerais de ne pas trop t’arrêter sur la définition de la typeclass Foldable
(que tu peux trouver ici), tu verras les folds et les typeclass plus en détail par la suite.
Pour ce qui est de ta question à proprement parler, la réponse est que t
est un type paramétré, c’est-à-dire un type dont le constructeur prend lui-même d’autres types en argument. On peut prendre l’exemple des listes, voici comment on peut les définir en Haskell:
| data List a = Cons a (List a)
| Nil
deriving (Show) -- `deriving` permet d'indiquer la typeclass
|
Notre liste ici est donc paramétrée par un autre type, on peut ainsi avoir des listes d’entiers, des listes de caractères, etc. Les listes étant extrêmement utilisées en Haskell, on a du sucre syntaxique pour pouvoir alléger le code: List a
devient simplement [a]
, Cons
est l’opérateur (:)
et Nil
est noté []
.
| foo :: List Int
foo = Cons 1 (Cons 2 (Cons 3 Nil))
foo_ :: [Int] -- equivalent a
foo_ = 1 : (2 : (3 : [])) -- foo_ = [1,2,3]
bar :: List Char
bar = Cons 'h' (Cons 'e' (Cons 'l' (Cons 'l' (Cons 'o' Nil))))
bar_ :: [Char] -- bar_ = ['H','e','l','l','o']
bar_ = 'H' : ('e' : ('l' : ('l' : ('o' : [])))) -- ou bar_ = "Hello"
|
Pour résumer, la signature de la fonction length
est bien correcte. length
opère sur un argument qui est obligatoirement un Foldable
(t
) et qui peut lui contenir n’importe quel type (a
). Si tu veux définir une fonction my_length
qui travaillerait uniquement sur des listes d’entiers, tu t’y prendrais comme ceci par exemple en le spécifiant dans la signature:
| my_length :: [Int] -> Int
my_length list = length list
foo = my_length [1, 2, 3] -- ==> 3
bar = my_length "Hello" -- ==> erreur de typage ([Char] au lieu de [Int])
|