Tout est dans le titre, mais je vais développer. J'ai écris une fonction assez pratique (que j'ai appelé assez maladroitement "point2", censé signifier "équivalent de l'operateur (.), mais la seconde fonction n'est appliquée qu'au niveau du deuxieme argument de la premiere fonction"). Voici sa définition:
en tout cas, c'est plutot utile si l'on veut combiner f et g mais avec g supposé retourner le *deuxieme* argument de f, pas le premier (ce qui serait le cas pour l'operateur (.))
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 point2 :: (a -> b -> c) -> (d -> b) -> (( a -> d -> c )) -- les doubles parenthèses sont bien sur inutiles pour le compilateur. elles sont uniquement là pour impliquer que les utilisateurs vont considérer la fonction comme retournant une autre fonction -- bien qu'évidemment celle-ci peut être appliquée directement, retournant une valeur de type c, ou peut-être (d -> c) si application partielle. -- J'ai nommé les variables dans le pattern avec les mêmes lettres que leurs types respectifs, pour "clarité" point2 f g a d = f a (g d) -- j'avais originellement écrit cette fonction en "point-free" style (je ne sais pas comment ça se dit en français) -- avec l'aide de la fonction flip, qui provient de Data.Function (pour être franc a l'origine j'avais surtout réinventé ma propre roue); -- donc, définition alternative en utilisant flip == (\f y x -> f x y) point2 f g = flip (flip f . g) -- preuve par décomposition: (ou bien peut etre "composition", vu qu'on ne decompose en fait rien du tout?) -- f :: a -> b -> c -- flip f :: b -> a -> c -- flip f . g :: d -> a -> c -- flip (flip f . g) == f `point2` g :: a -> d -> c
dans l'expression de gauche, "a" doit etre donné pour utiliser cette définition en "point-free" style; dans le second cas, "a" peut être omit, et on peut alors écrire "foo = f `point2` g", ce qui est bien plus proche du style "point-free", et bien plus simple à comprendre à mon avis, une fois que l'on a assimilé ce que fait cette fonction "point2".
Code : Sélectionner tout - Visualiser dans une fenêtre à part (f a) . g == (f `point2` g) a
Si vous avez suivi depuis le début, ma question est donc: est-ce que cette fonction existe déjà officiellement quelque part; je n'ai pas envie de réinventer la roue, et je suis curieux du nom que cette fonction pourrait porter, pare que je ne suis pas mortellement satisfait de "point2". j'adorerais un truc du genre (.2) mais ça n'est pas compatible avec haskell.
Aussi, j'avais oublié, même question pour la fonction suivante, encore une petite soeur de la fonction (.). Ici le but est de pouvoir écrire h a b = f (g a b) en mode "point-free".
si vous connaissez Data.Function(on), en gros "after2" est un peu son opposée, ou l'une d'entre elles: `on` appliques g aux deux arguments de f indépendamment, avant de donner les deux résultats à f qui elle prends effectivement deux arguments (maximum, devrais-je dire):
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 after2 :: (c -> d) -> (a -> b -> c) -> (( a -> b -> d )) after2 f g a b = f (g a b) -- le nom de cette fonction implique un usage infixe, par exemple for example: h = f `after2` g
Accessoirement, je suis pratiquement sur que l'ont peut écrire:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 on :: (c -> c -> d) -> (e -> c) -> (( e -> e -> d )) -- (f `on` g) a b == f (g a) (g b) -- a et b sont de type "e" bien sur
Au cas où, les définitions des deux fonctions (un)curry:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 f `after2` g == curry (f . (uncurry g)) -- puisque, en utilisant la meme notation que la definition de after2 ci dessus: -- uncurry g :: (a,b) -> c -- f . uncurry g :: (a,b) -> d -- curry (f . uncurry g) :: a -> b -> d
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 curry :: ((a,b) -> c) -> a -> b -> c -- curry f a b = f (a,b) -- curry f :: a -> b -> c, lorsque f :: (a,b) -> c uncurry :: (a -> b -> c) -> (a, b) -> c -- uncurry g (a,b) = g a b -- uncurry g :: (a,b) -> c, lorsque g :: a -> b -> c
Partager