Recherche…


Remarques

Éclaircissons certaines idées fausses que les débutants pourraient faire.

Vous avez peut-être rencontré des fonctions telles que:

max :: (Ord a) => a -> a -> a  
max m n  
  | m >= n = m  
  | otherwise = n  

Les débutants afficheront généralement la fonction max :: (Ord a) => a -> a -> a qui prend deux arguments (valeurs) de type a et renvoie une valeur de type a . Cependant, ce qui se passe réellement, c'est que max prend un argument de type a et renvoie une fonction de type a -> a . Cette fonction prend alors un argument de type a et retourne une valeur finale de type a .

En effet, max peut être écrit comme max :: (Ord a) => a -> (a -> a)

Considérons le type signature de max :

Prelude> :t max  
max :: Ord a => a -> a -> a  

Prelude> :t (max 75)  
(max 75) :: (Num a, Ord a) => a -> a  

Prelude> :t (max "Fury Road")  
(max "Fury Road") :: [Char] -> [Char]  

Prelude> :t (max "Fury Road" "Furiosa")  
(max "Fury Road" "Furiosa") :: [Char]  

max 75 et max "Fury Road" peuvent ne pas ressembler à des fonctions, mais en réalité, elles le sont.

La confusion provient du fait qu'en mathématiques et dans de nombreux autres langages de programmation courants, nous sommes autorisés à avoir des fonctions qui prennent plusieurs arguments. Cependant, dans Haskell, les fonctions ne peuvent prendre qu'un seul argument et peuvent renvoyer des valeurs telles que a ou des fonctions telles que a -> a .

Fonction d'ajout partiellement appliquée

Nous pouvons utiliser une application partielle pour "verrouiller" le premier argument. Après avoir appliqué un argument, on se retrouve avec une fonction qui attend un argument supplémentaire avant de renvoyer le résultat.

(+) :: Int -> Int -> Int

addOne :: Int -> Int
addOne = (+) 1

Nous pouvons alors utiliser addOne pour en ajouter un à un Int .

> addOne 5
6
> map addOne [1,2,3]
[2,3,4]

Renvoi d'une fonction partiellement appliquée

Renvoyer des fonctions partiellement appliquées est une technique pour écrire du code concis.

add :: Int -> Int -> Int
add x = (+x)

add 5 2

Dans cet exemple (+ x) est une fonction partiellement appliquée. Notez que le deuxième paramètre de la fonction add n'a pas besoin d'être spécifié dans la définition de fonction.

Le résultat de l'appel à l' add 5 2 est sept.

Sections

La section est un moyen concis d'appliquer partiellement des arguments à des opérateurs infixés.

Par exemple, si nous voulons écrire une fonction qui ajoute "ing" à la fin d'un mot, nous pouvons utiliser une section pour définir succinctement une fonction.

> (++ "ing") "laugh"
"laughing"

Remarquez comment nous avons partiellement appliqué le deuxième argument. Normalement, nous ne pouvons appliquer que partiellement les arguments dans l'ordre spécifié.

Nous pouvons également utiliser la section gauche pour appliquer partiellement le premier argument.

> ("re" ++) "do"
"redo"

Nous pourrions écrire ceci de manière équivalente en utilisant une application partielle de préfixe normale:

> ((++) "re") "do"
"redo"

Une note sur la soustraction

Les débutants sectionnent souvent incorrectement la négation.

> map (-1) [1,2,3]
***error: Could not deduce...

Cela ne fonctionne pas car -1 est analysé en tant que littéral -1 plutôt que l'opérateur sectionné - appliqué à 1 . La fonction de subtract existe pour contourner ce problème.

> map (subtract 1) [1,2,3]
[0,1,2]


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow