30 votes

Programmation fonctionnelle du monde réel à Scala

Soooo...

Semigroups, Monoids, les Monades, Foncteurs, les Lentilles, les Catamorphisms, Anamorphisms, des Flèches... tout son bien, et après un exercice ou deux (ou dix), vous pouvez saisir leur essence. Et avec Scalaz, vous obtenez gratuitement...

Cependant, en termes de programmation, je me trouve mal à trouver des usages de ces notions. Oui, bien sûr, j'ai toujours trouver quelqu'un sur le web à l'aide de Monades IO ou de Lentilles en Scala, mais... encore...

Ce que j'essaie de trouver est quelque chose le long de la "prescriptive" lignes d'un dessin. Quelque chose comme: "ici, vous essayez d'résout ce, et une bonne façon de résoudre c'est par l'utilisation de lentilles de cette façon!"

Des Suggestions?


Mise à jour: quelque Chose le long de ces lignes, avec un livre ou deux, serait génial (merci Paul): Exemples de Design Patterns GoF

18voto

Dan Burton Points 26639

La clé de la programmation fonctionnelle est l'abstraction, et la composabilité des abstractions. Les monades, des Flèches, des Lentilles, ce sont toutes les abstractions qui se sont avérés utiles, surtout parce qu'ils sont composables. Vous avez demandé un "prescriptive" réponse, mais je vais dire non. Peut-être que vous n'êtes pas convaincu que la programmation fonctionnelle des questions?

Je suis sûr que beaucoup de gens sur StackOverflow serait plus qu'heureux de l'essayer et de vous aider à résoudre spécifiques du problème de la FP façon. Avoir une liste de trucs et que vous souhaitez parcourir la liste et faire une suite? L'utilisation d'un pli. Souhaitez analyser XML? hxt utilise les flèches pour cela. Et les monades? Ainsi, des tonnes de types de données s'avèrent être des Monades, afin d'apprendre à leur sujet et vous découvrirez une multitude de façons que vous pouvez manipuler ces types de données. Mais son genre de difficile d'en tirer des exemples hors de l'air mince et dire "les lentilles sont la bonne Façon de le faire", "monoids sont la meilleure façon de le faire", etc. Comment expliquer à un novice à ce que l'utilisation d'une boucle for? Si vous voulez [vide], puis utiliser une boucle for [de cette façon]. C'est tellement général; il y a des tonnes de façons d'utiliser une boucle for. Il en va de même pour ces FP abstractions.

Si vous avez de nombreuses années de la programmation orientée objet de l'expérience, alors n'oubliez pas vous avez été une fois un débutant en programmation orientée objet. Il faut du temps pour apprendre la FP façon, et même plus de temps à désapprendre certaines tendances de la programmation orientée objet. Donnez-lui du temps et vous en trouverez beaucoup d'utilisations pour une approche Fonctionnelle.

12voto

oxbow_lakes Points 70013

J'ai donné une conférence en septembre axé sur l'application pratique de monoids applicative et foncteurs/monades via scalaz.La Validation. J'ai fait une autre version du même discours à la scala "Lift-Off", où l'accent est mis davantage sur la validation. Je voudrais regarder le premier parler jusqu'à ce que je commence sur les validations et passez ensuite à la seconde conférence (27 minutes).

Il y a également un résumé que j'ai écrit qui montre comment vous pouvez utiliser la Validation en une "pratique" de l'application. C'est, si vous êtes de la conception de logiciels pour des videurs de boîte de nuit.

6voto

huynhjl Points 26045

Je pense que vous pouvez prendre l'inverse de l'approche et de la place lors de l'écriture d'un petit morceau de fonctionnalités, demandez-vous si une de celles-ci s'appliquent: Semigroups, Monoids, les Monades, Foncteurs, les Lentilles, les Catamorphisms, Anamorphisms, des Flèches... beaucoup de ces concepts peuvent être utilisés au niveau local.

Une fois que vous commencez en bas de cette route, vous pouvez voir l'utilisation de partout. Pour moi, j'ai en quelque sorte de l'obtenir Semigroups, Monoids, les Monades, les Foncteurs. Alors, prenez l'exemple de répondre à cette question, Comment dois-je remplir une liste d'objets avec de nouvelles valeurs. C'est un réel usage pour la personne qui pose la question (une auto décrit noob). Je suis en train de répondre de façon simple, mais j'ai de s'abstenir de me gratter la démangeaison "il y a monoids ici".

Le grattage il maintenant: à l'aide d' foldMap et le fait que Int et de la Liste sont monoids et que le monoïde de la propriété est conservée lorsque vous traitez avec tuple, de cartes et d'options:

// using scalaz
listVar.sliding(2).toList.foldMap{
  case List(prev, i) => Some(Map(i -> (1, Some(List(math.abs(i - prev))))))
  case List(i) => Some(Map(i -> (1, None)))
  case _ => None
}.map(_.mapValues{ case (count, gaps) => (count, gaps.map(_.min)) })

Mais je ne viens pas à ce résultat en pensant que je vais utiliser pour le noyau dur de la programmation fonctionnelle. Il vient plus naturellement par la pensée, cela semble plus simple si je compose ces monoids combiné avec le fait que scalaz a des méthodes de l'utilitaire, comme foldMap. Fait intéressant, lorsque l'on regarde le code résultant, il n'est pas évident, je suis tout à fait de penser en termes de monoïde.

6voto

missingfaktor Points 44003

Vous pourriez, comme ce parler par Chris Marshall. Il couvre un couple de Scalaz goodies - à savoir Monoïde et de Validation - avec de nombreux exemples pratiques. Ittay Dror a écrit une très accessible post sur comment Foncteur, Applicative Foncteur, et la Monade peut être utile dans la pratique. Eric Torreborre et Debasish Gosh's les blogs ont aussi un tas de postes couvrant les cas d'utilisation pour catégorique des constructions.

Cette réponse juste énumère quelques-unes des liens au lieu de la fourniture d'une substance réelle ici. (Trop paresseux pour écrire.) J'espère que vous trouverez utile de toute façon.

3voto

Blaisorblade Points 3951

Je comprends votre situation, mais vous verrez que d'apprendre la programmation fonctionnelle, vous aurez besoin d'ajuster votre point de vue à la documentation que vous trouverez, au lieu de l'inverse. Heureusement, en Scala, vous avez la possibilité de devenir un programmeur fonctionnel progressivement.

Pour répondre à vos questions et expliquer le point de vue de la différence, j'ai besoin de distinguer entre les "classes de type" (monoids, foncteurs, flèches), mathématiquement appelle les "structures", et générique des opérations ou des algorithmes (catamorphisms ou des plis, anamorphisms ou se déroule, etc.). Ces deux interagissent souvent, depuis de nombreux génériques opérations sont définies pour des catégories spécifiques de types de données.

Vous recherchez normative des réponses similaires aux modèles de conception: lorsque ce concept s'applique? La vérité est que vous avez sûrement vu les réponses normatives, et ils sont tout simplement les définitions des différents concepts. Le problème (pour vous) c'est que ces réponses sont intrinsèquement différents des modèles de conception, mais il l'est pour de bonnes raisons.

D'une part, des algorithmes génériques ne sont pas des modèles de conception, qui suggèrent une structure pour le code que vous écrivez; ils sont des abstractions défini dans la langue que vous pouvez appliquer directement. Ils sont des descriptions générales pour le commun des algorithmes qui vous mettent déjà en œuvre aujourd'hui, mais à la main. Par exemple, si vous êtes le calcul de l'élément maximum d'une liste par l'analyse, vous êtes coder en dur une fois; lorsque vous somme des éléments, vous faites la même chose, et ainsi de suite. Lorsque vous reconnaissez que, vous pouvez déclarer l'essence de l'opération effectuée par un appel à la appropriée de la fonction fold. De cette façon, vous économisez de code et de bugs (pas de possibilité pour tout-en-un d'erreurs), et que vous enregistrez le lecteur l'effort de lire tout le code nécessaire.

D'autre part, les structures ne concernent pas l'objectif que vous avez à l'esprit, mais les propriétés des entités vous êtes à la modélisation. Ils sont plus utiles pour les bas-logiciel de construction, plutôt que de haut en bas: lors de la définition de vos données, vous pouvez déclarer que c'est un par exemple un monoïde. Plus tard, lors du traitement de vos données, vous avez la possibilité d'utiliser des opérations sur, par exemple, monoids pour mettre en œuvre votre traitement. Dans certains cas, il est utile de s'efforcer d'exprimer votre algorithme en termes de prédéfinis. Par exemple, très souvent, si vous avez besoin de réduire un arbre à une valeur unique, un pli peut faire la plupart ou la totalité de ce que vous avez besoin. Bien sûr, vous pouvez également déclarer votre type de données est un monoïde lorsque vous avez besoin d'un algorithme générique sur monoids; mais le plus tôt vous remarquez que, le plus tôt vous pouvez commencer à la réutilisation des algorithmes génériques pour monoids.

Dernier conseil, c'est que probablement la plupart de la documentation que vous trouverez sur ces concepts préoccupations Haskell, parce que cette langue a été autour pendant beaucoup plus de temps et les soutient dans un assez élégant. Tout à fait recommandé, voici Apprendre que vous avez un Haskell pour le Grand Bien, un Haskell cours pour les débutants, où entre autres les chapitres 11 à 14 focus sur certaines classes de type, et Typeclassopedia (qui contient des liens vers divers articles avec des exemples précis). EDIT: Enfin, un exemple d'applications de Monoids, prises de Typeclassopedia, c'est ici: http://apfelmus.nfshost.com/articles/monoid-fingertree.html. Je ne dis pas qu'il y a peu de documentation pour la Scala, juste qu'il y a de plus en Haskell, et Haskell est où l'application de ces concepts à la programmation était né.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X