10
votes

Modèle de conception de foncteur dans HASKELLL

Je m'excuse de ne pas avoir de bon titre pour cette question. J'ai eu des problèmes d'exprimer ce dont j'ai besoin. J'ai un simple problème dans Haskell et je me demande quelle est la meilleure approche consiste à le résoudre.

Disons que j'ai une liste de chiffres: [- 3,2,1,2] code>. Je veux retourner la valeur avec la valeur absolue la plus élevée. C'est-à-dire que je veux retourner -3. Donc, je veux: p> xxx pré>

Le problème est, bien sûr, que cela renvoie la valeur calculée (3) et non la valeur d'origine (-3). P> Je pouvais trouver une façon de le faire, cartographier la liste d'origine à un tuple de (originalValue, CalculatDvalue), trouvant le tuple dont la SND est renvoyée par ma fonction (maximum) puis de retourner la FST de ce tuple. P>

Mais cela ressemble à beaucoup de "plomberie" pour un simple problème comme celui-ci, et je me demande s'il y a une abstraction qui me manque, cela résout cela. C'est-à-dire qu'il y a cette procédure généralement que je fais tout le temps et je veux un moyen de le faire soigneusement: p>

  1. Je veux prendre une liste d'articles. Li>
  2. Je veux les cartonner à une certaine valeur (disons la valeur absolue) li>
  3. Ensuite, je veux en choisir un en fonction de certains critères (disons que je veux le maximum ou peut-être le minimum). LI>
  4. Mais alors je veux retourner la valeur originale em>. (Si la liste était [- 3,2,1,2] code> et je veux retourner la valeur avec les abdominaux les plus élevés, alors je retournerais -3). Li> OL>

    Y a-t-il une fonction de bibliothèque pour cela? Existe-t-il un foncteur ou une monade pour cela? P>

    Je pense que je veux une fonction avec la signature: p> xxx pré>

    IE p>

    f maximum abs [-3,2,1,2]
    


0 commentaires

6 Réponses :


20
votes

Utilisez Matériellement, qui prend une fonction de comparaison. Vous pouvez ensuite passer une fonction qui compare la façon dont vous voulez.

maximumBy (compare `on` abs)


4 commentaires

Ou équivalent: maximum par (comparer ABS)


Je préfère utiliser sur , car cela fonctionne avec d'autres choses, par exemple ,. (==) sur ABS).


Merci pour votre solution! Il y a un maximum et un minimum. Y a-t-il un fondfirstby? Je suppose qu'il y a beaucoup de fonctions qui prennent une et la transforment en un B (ABS), puis de nombreuses fonctions qui prennent une [B] et la transforment en B (maximum). Et j'essaie de trouver une façon de les composer généralement sans le cuire.


@Ara: la fonction ELEMInDex dans la fonction data.List Module donne l'index du premier élément dans une liste qui satisfait un prédicat donné. S'il n'y a pas d'élément de correspondance, rien est retourné. Cela pourrait être ce que vous envisagez lorsque vous parlez de FindFirstby .



1
votes

Je crois que quelque chose sur les lignes de ce qui suit devrait fonctionner. XXX

Au-delà de la tâche à la main, vous pourriez la généraliser en résumant la fonction de comparaison et en le transmettant plus tard.


0 commentaires

1
votes

Voici quelque chose que j'ai cuisiné. C'est une sorte de meh, car elle nécessite (EQ B) xxx pré>

, puis: p> xxx pré>

ou: p>

selectOn sum id [-3, 0, 3]


0 commentaires

3
votes

Si vous essayez d'avoir quelque chose de commandé et comparé par une projection toujours, plutôt que juste à une utilisation spécifique (auquel cas voir la réponse d'Augusts), utilisez une nouvelle wrapper: xxx pré>

Maintenant, par exemple: p>

(maximum [1,2,-3] :: AbsInt) = AbsInt (-3)


0 commentaires

8
votes

Stop ... HOILE TIME!

Vous avez donc une liste de choses [a] . Et vous voulez vous retrouver avec juste un de ces A . Vous souhaitez également comparer des éléments de cette liste de manière particulière (pas leur ordre naturel), afin de déterminer qui vient en premier. C'est la partie délicate, mais vous devriez être capable de voir que ce que j'ai décrit est une fonction du formulaire a -> a -> commande . .

Mettez tout ensemble:

(A -> A -> Commande) -> [a] -> A

et hoogle il . Maximumby et MinuünBy Les premiers hits :) HOOGLE peut être un atout puissant lorsque vous apprenez à l'utiliser. (Voir la réponse d'Augusts pour plus de détails sur l'utilisation de maximum, dans ce cas)


0 commentaires

6
votes

Une autre façon de le faire, si la conversion est un peu chère: xxx

Ce type est similaire à ghc.extes 's Sortwith , qui nous donne un autre façon de le faire: xxx

Nous pouvons définir un minimum avec un minimum: xxx

un regard sur la source de Sortwith révèle qu'il est implémenté par Sortby , il manque donc de la mise en cache que la première définition pour Maximumbith

Ceci, évidemment Appelle à une analyse comparative: xxx

Les résultats sur mon ordinateur portable: xxx


0 commentaires