J'ai lu un article qui a déclaré: p>
Fournir des instances pour les nombreuses classes de type standard [foncteurs] vous donnera immédiatement beaucoup de fonctionnalités pour pratiquement libres p> blockQuote>
Ma question est la suivante: quelle est cette fonctionnalité que vous obtenez gratuitement (pour les foncteurs ou autres classes de type)? Je sais quelle est la définition d'un foncteur, mais que dois-je obtenir pour libre fort> en définissant quelque chose comme un foncteur / autre classe de type. Autre chose qu'une syntaxe plus jolie. Idéalement, ce serait des fonctions générales et utiles qui fonctionnent sur les foncteurs / autres classes de type. P>
Mon imagination (pourrait être incorrect) de quel moyen libre est des fonctions de ce type:
Typeclass x => utile x y = .. code> p> p> P>
== EDIT / ADDITITION == P>
Je suppose que je demande principalement aux classes de type plus abstraites (et cérébrales), telles que celles dans cette image . Pour des classes moins abstraites comme ORD, mon intuition orientée objet comprend. P>
6 Réponses :
Il existe de nombreuses fonctions standard dans HASKELL qui nécessitent que leurs arguments mettent en œuvre une ou plusieurs classes de type. Ce faisant dans votre code permet aux autres développeurs (ou vous-même) d'utiliser vos données de manière déjà familiarisée, sans avoir à écrire des fonctions supplémentaires. P>
À titre d'exemple, la mise en œuvre de la classe Type d'ordonnance vous permettra d'utiliser des éléments comme Trier, Min, Max, etc. Où autrement, vous auriez besoin de SORBY et similaire. P>
Oui, cela signifie que la mise en œuvre de la classe de type La classe de type code> Foncteur code> n'est pas trop intéressante à cet égard, car il ne vous donne pas beaucoup de choses. P>
Un meilleur exemple est la monade et les fonctions du module Certains des plus utiles incluent: foo code> vous donne toutes les autres fonctions qui ont un
FOO code> contrainte "gratuitement". P>
Control.monad code>. Une fois que vous avez défini les deux
monad code> Fonctions
(>> =) code> et
retour code> pour votre type, vous obtenez une autre ou deux fonctions qui peuvent puis être utilisé sur votre type. P>
mapm code>,
séquence code>,
pour toujours code>,
joindre code>,
,
FILEM code>,
FilterM code>,
réplicatem code>,
lorsque code>,
, sauf si code> et
lifting code> . Celles-ci montrent tout le temps dans le code Haskell. P>
Les foncteurs sont simples et probablement pas le meilleur exemple. Regardons la monade à la place: p>
liftm code> - Si quelque chose est une monade, il s'agit également d'un foncteur où liftm code> est fmap code>. li>.
-
> => code>, <= << / code>: vous pouvez composer a -> mb code> fonctionne gratuitement où m code > Votre monade est-elle? Li>
-
FILEM, MAPM, FILETM CODE> ... Vous obtenez un tas de fonctions utilitaires généralisant les fonctions existantes à utiliser votre monade. LI>
-
quand code>, garde code> grève> * et sauf si code> - Vous obtenez également des fonctions de contrôle gratuitement. li>
-
rejoindre code> - Ceci est en fait assez fondamental pour la définition d'une monade, mais vous n'avez pas besoin de le définir dans HASKELL, car vous avez défini >> = code >. li>
- Transformers -
Errort code> etc. Vous pouvez verser une erreur d'erreur sur votre nouveau type gratuitement (donner ou prendre)! Li>
ul>
Fondamentalement, vous obtenez une grande variété de fonctions standard "levées" pour utiliser votre nouveau type dès que vous en faites une instance monad code>. Il devient également trivial (mais hélas non automatique) pour en faire un document code> et applicatif code> aussi. P>
Cependant, ce sont tous des "symptômes" d'une idée plus générale. Vous pouvez écrire un code intéressant et non trivial qui s'applique à tous em> monads. Vous trouverez peut-être certaines des fonctions que vous avez écrites pour votre type - qui sont utiles dans votre cas particulier, pour une raison quelconque - peut être généralisée à toutes les monades. Maintenant, vous pouvez soudainement prendre votre fonction et l'utiliser sur des analyseurs, des listes et des maybes et ... p>
* Comme Daniel Fischer souligné utilement, Guard Code> nécessite monadplus code> plutôt que monad code>. P>.
garde code> nécessite
monadplus code>.
Comme il semble que ce ne semble être une poignée de ces fonctions de bibliothèque, même pour la monade qui est une assez belle classe de type riche, je terminerais, il est peu probable qu'il se produise. C'est théoriquement i> possible que votre code puisse généraliser par magie à toutes les monades, mais pratiquement s'ils existaient, je verrais beaucoup plus de fonctions utiles pour les monades.
Les foncteurs ne sont pas très intéressants par eux-mêmes, mais ils sont un tremplin nécessaire pour entrer dans des foncteurs applicatifs et traverse code>
. P>
La propriété principale qui rend les foncteurs d'applications utiles est que vous pouvez utiliser Monads sont l'une des classes de type les plus intéressantes et utiles, mais elles sont déjà bien couvertes par les autres réponses. P>
fmap code> avec l'opérateur d'applications
<*> code> pour "soulever" n'importe quelle fonction de n'importe quelle arité pour travailler avec valeurs applicatives. C'est à dire. Vous pouvez transformer tout
a -> b -> c-> d code> dans
applicatif f => f A -> f b -> f C -> f d code>. Vous pouvez également jeter un coup d'œil à
.Traverable code>
et data.LeLeLe code>
contient plusieurs fonctions à usage général qui impliquent des foncteurs applicatifs. P>
alternatif Code>
est un foncteur d'application spécialisé qui prend en charge le choix entre des solutions de rechange pouvant "échouer" (la signification exacte de "vide" dépend de l'instance applicative). Les analyseurs applicatifs sont un exemple pratique où les définitions de certains code> et
de nombreux code> sont très intuitives (par exemple, assortir un modèle zéro-ou-plusieurs fois ou une fois d'un ou plusieurs fois). p>
monoïde code>
est une autre classe de type qui est à la fois simple et immédiate. Il définit essentiellement un moyen d'ajouter deux pièces de données ensemble, ce qui vous donne ensuite un Concat code> ainsi que des fonctionnalités dans le module susmentionné
pliable code> et vous permet également d'utiliser
écrivain code>
monade avec le type de données. P>
Comme d'autres l'ont dit, le fonctionnement lui-même ne vous a pas réellement géré gratuitement. Fondamentalement, le plus haut niveau ou général une typlass est (ce qui signifie que plus les choses correspondent à cette description), la fonctionnalité moins "libre" que vous allez obtenir. Donc, par exemple, le fonctionnement et le monoïde ne vous fournissent pas beaucoup, mais la monade et la flèche vous fournissent de nombreuses fonctions utiles gratuitement. P>
in Haskell, il est toujours judicieux d'écrire une instance pour le fonctionnement et le monoïde (si votre type de données est effectivement un foncteur ou un monoïde), car nous essayons presque toujours d'utiliser l'interface la plus générale possible lorsque vous écrivez des fonctions. Si vous écrivez une nouvelle fonction qui peut vous échapper uniquement à l'aide de fmap code> pour fonctionner sur votre type de données, il n'y a aucune raison de restreindre artificiellement la fonction à
monad code> S ou
applicatif code> s, car cela pourrait être utile ultérieurement pour d'autres choses. P>
Votre intuition orientée objet effectue, si vous lisez «Interface et mise en œuvre» pour «Typique et instance». Si vous faites votre nouveau type C une instance d'une typlasse standard B, vous obtenez gratuitement que votre type fonctionnera avec tout le code existant A qui dépend de b. P>
p> blockQuote>
Comme d'autres l'ont dit, lorsque la typlass est quelque chose comme
monad code>, les Freebies sont les nombreuses fonctions de la bibliothèque telles que
FILEM code> et
quand code>. p>