11
votes

Pourquoi le pli reste-t-il attendu (A -> B -> A) au lieu de (B -> A -> A)?

Je me demande pourquoi la fonction attendue par le pli à gauche a une signature de type a -> b -> a au lieu de b -> a -> a . Y a-t-il une décision de conception derrière cela?

in Haskell, par exemple, je dois écrire plipl (\ xs x -> x: xs) [] xs pour inverser une liste à la place du fichier plus court (:) [ ] XS (qui serait possible avec B -> A -> A ). D'autre part, il existe des cas d'utilisation qui nécessitent la norme a -> b -> a . Dans Scala, cela pourrait être ajouté: xs.foltleft (list.empty [int]) ((xs, x) => xs: + x) qui peut être écrit comme xs.foldleft (List.empty [int]) (_: + _) .

Faites proportionnellement plus d'usages d'utilisation nécessitant la signature de type donnée au lieu de l'autre, ou existe-t-il d'autres décisions qui ont conduit à la conception qui se trouve à gauche dans HASKELLL et SCALA (et probablement beaucoup d'autres langues)?


2 commentaires

En d'autres termes, vous devez inverser l'ordre d'argument de (:) afin d'inverser une liste. A du sens pour moi.


Notez que mapaccuml et mapaccumr (à partir de data.list / data.traverable ) ont la même signature, bien qu'ils Travaillez aussi dans des directions opposées.


4 Réponses :


4
votes

parce que vous écrivez (a /: bs) pour repliolft sous forme abrégée; Ceci est un opérateur qui appuie A via tous les BS , il est donc naturel d'écrire la fonction de la même manière (c.-à-d. (A, B) => A ). Notez que flambight est-ce dans l'autre ordre.


1 commentaires

Nice, mais cela ne l'expliquera que pour Scala pas dans Haskell qui n'a pas /: .



30
votes

Conceptuellement, un pli droit, dire pli FZ [1..4] remplace une liste du formulaire suivant xxx

avec la valeur d'une expression de la forme suivante xxx

Si nous devions représenter cette expression sur une seule ligne, toutes les parenthèses s'associeraient à droite, d'où le nom droit pli: (1 `f` (2` f` (3 `f` (4` f` z)))) . Un pli gauche est double dans un sens à un pli droit. En particulier, nous aimerions que la forme du diagramme correspondant pour un pli gauche soit une image miroir de celle pour un pli gauche, comme dans les suivants: xxx

si Nous devions écrire ce diagramme sur une seule ligne, nous obtiendrions une expression où toutes les parenthèses associent à gauche, qui se jibrent bien au nom d'un pli gauche: xxx

Mais remarquez que dans ce diagramme de miroir, le résultat récursif du pli est introduit à F comme premier argument, tandis que chaque élément de la liste est alimenté comme deuxième argument, c'est-à-dire que les arguments sont destinés à f dans l'ordre inverse par rapport aux plis droit.


0 commentaires

7
votes

La signature de type est Foldl :: (A -> B -> A) -> A -> [B] -> A ; Il est naturel que la fonction de combinaison ait la valeur initiale à gauche, car c'est la façon dont il se combine avec les éléments de la liste. De même, vous remarquerez replier l'a l'inverse. La complication de votre définition de l'inverse est que vous utilisez une expression lambda où flip aurait été plus agréable: plipl (Flip (:)) [] xs , lequel a la similitude agréable entre les concepts de flip et d'inverse.


0 commentaires

2
votes

dire que vous avez ceci: xxx

c'est la même que: xxx

Voir comment le premier paramètre est toujours l'accumulateur? Avoir les paramètres de cette commande rend la syntaxe de plachalder (le soulignement) une traduction directe vers l'expression expansée.


0 commentaires