217 votes

De bons exemples de Pas un Foncteur/Foncteur/Applicatif/Monade?

Tout en expliquant à quelqu'un ce qu'est une classe de type X est j'ai du mal à trouver de bons exemples de structures de données qui sont exactement X.

Donc, je demande des exemples pour:

  • Un constructeur de type qui n'est pas un Foncteur.
  • Un constructeur de type, qui est un Foncteur, mais pas Applicative.
  • Un constructeur de type, qui est un Applicative, mais n'est pas une Monade.
  • Un constructeur de type, qui est une Monade.

Je pense qu'il y a beaucoup d'exemples de Monade partout, mais un bon exemple de la Monade avec certains rapport aux exemples précédents pourraient compléter le tableau.

Je regarde pour les exemples qui seraient semblables les uns aux autres, ne différant que par les aspects importants de l'appartenance à un type particulier de la classe.

Si l'on pouvait réussir à se faufiler un exemple de la Flèche, quelque part dans cette hiérarchie (est-il entre Applicative et de la Monade?), ce serait très bien aussi!

102voto

Dietrich Epp Points 72865

Un constructeur de type qui n'est pas un Foncteur:

newtype T a = T (a -> Int)

Vous pouvez faire un cofunctor, mais pas un foncteur. Essayez d'écrire fmap et vous allez échouer. Notez que le cofunctor version est inversé:

fmap   :: Functor f   => (a -> b) -> f a -> f b
cofmap :: Cofunctor f => (a -> b) -> f b -> f a

Un constructeur de type, qui est un foncteur, mais pas Applicative:

Je n'ai pas un bon exemple. Il est Const, mais, idéalement, j'aimerais un béton non-Monoïde et je ne peux pas penser à tout. Tous les types sont essentiellement numériques, des énumérations, des produits, des sommes ou des fonctions lorsque vous descendez à elle. Vous pouvez voir ci-dessous pigworker et j'en désaccord quant à savoir si Data.Void est Monoid;

instance Monoid Data.Void where
    mempty = undefined
    mappend _ _ = undefined
    mconcat _ = undefined

Depuis _|_ est une valeur juridique en Haskell, et en fait, la seule valeur juridique d' Data.Void, cela correspond à l'Monoïde règles. Je suis pas sûr de ce qu' unsafeCoerce a à faire avec elle, parce que votre programme n'est plus garanti de ne pas violer Haskell sémantique dès que vous utilisez un unsafe fonction.

Voir le Haskell Wiki pour un article sur le fond (lien) ou dangereux fonctions (lien).

Je me demande si il est possible de créer un tel type de constructeur à l'aide d'un riche système de type, comme les Agda ou Haskell avec diverses extensions.

Un constructeur de type, qui est un Applicative, mais pas une Monade:

newtype T a = T {multidimensional array of a}

Vous pouvez faire un Applicative hors de lui, avec quelque chose comme:

mkarray [(+10), (+100), id] <*> mkarray [1, 2]
  == mkarray [[11, 101, 1], [12, 102, 2]]

Mais si vous en faites une monade, vous pourriez obtenir une dimension l'inadéquation. Je soupçonne que des exemples de ce genre sont rares dans la pratique.

Un constructeur de type, qui est une Monade:

[]

À Propos De Flèches:

Demandant où une Flèche se trouve sur cette hiérarchie, c'est comme demander quel genre de forme "rouges". Remarque le type de discordance:

Functor :: * -> *
Applicative :: * -> *
Monad :: * -> *

mais,

Arrow :: * -> * -> *

89voto

pigworker Points 20324

Mon style peut être à l'étroit par mon téléphone, mais voilà.

newtype Not x = Kill {kill :: x -> Void}

ne peut pas être un Foncteur. Si c'était le cas, nous aurions

kill (fmap (const ()) (Kill id)) () :: Void

et la Lune serait faite de fromage vert.

Pendant ce temps

newtype Dead x = Oops {oops :: Void}

est un foncteur

instance Functor Dead where
  fmap f (Oops corpse) = Oops corpse

mais ne peut pas être applicative, ou nous aurions

oops (pure ()) :: Void

et le Vert de la Lune de fromage (ce qui peut réellement se produire, mais seulement plus tard dans la soirée).

(Note: Nulle, comme dans les Données.Le vide est un vide type de données. Si vous essayez d'utiliser indéfini à prouver que c'est un Monoïde, je vais utiliser unsafeCoerce pour prouver qu'il ne l'est pas.)

Joyeusement,

newtype Boo x = Boo {boo :: Bool}

est d'application dans de nombreuses façons, par exemple, que Dijkstra,

instance Applicative Boo where
  pure _ = Boo True
  Boo b1 <*> Boo b2 = Boo (b1 == b2)

mais il ne peut pas être une Monade. À voir, pourquoi pas, d'observer que le retour doit être constamment Boo Vrai ou Boo Faux, et donc que

join . return == id

ne peut pas tenir.

Ah oui, j'ai presque oublié

newtype Thud x = The {only :: ()}

est une Monade. Rouler votre propre.

Prendre l'avion...

77voto

Petr Pudlák Points 25113

Je crois que les autres réponses manqué certains simples et des exemples courants:

Un constructeur de type, qui est un Foncteur, mais pas un Applicative. Un exemple simple est une paire de:

instance Functor ((,) r) where
    fmap f (x,y) = (x, f y)

Mais il n'y a aucun moyen de savoir comment définir sa Applicative de l'instance sans imposer des restrictions supplémentaires sur l' r. En particulier, il n'existe aucun moyen de savoir comment définir pure :: a -> (r, a) pour un arbitraire r.

Un constructeur de type, qui est un Applicative, mais n'est pas une Monade. Un exemple bien connu est ZipList. (C'est un newtype qui encapsule les listes et fournit différents Applicative exemple pour eux.)

fmap est défini de la manière habituelle. Mais pure et <*> sont définies comme

pure x                    = ZipList (repeat x)
ZipList fs <*> ZipList xs = ZipList (zipWith id fs xs)

donc, pure crée une liste infinie en répétant la valeur donnée, et <*> zips une liste de fonctions avec une liste de valeurs - s'applique i-ème fonction de i-ème élément. (La norme <*> sur [] produit toutes les combinaisons possibles de l'application de la i-ème fonction de j-ième élément.) Mais il n'y a pas de bon sens comment définir une monade (voir ce post).


Comment flèches ajustement dans le foncteur/applicatif/monade hiérarchie? Voir les Idiomes sont des inconscients, des flèches sont méticuleux, les monades sont promiscuité par Sam Lindley, Philip Wadler, Jeremy Yallop. MSFP 2008. (Ils s'appellent les foncteurs applicatifs idiomes.) Le résumé:

Nous revisitons la connexion entre les trois notions de calcul: Moggi de monades, Hughes de flèches et de McBride et Paterson idiomes (également appelé foncteurs applicatifs). Nous montrons que les expressions idiomatiques sont équivalentes à des flèches qui satisfont le type isomorphisme ~> B = 1 ~> (A -> B) et que les monades sont équivalentes à des flèches qui satisfont le type isomorphisme ~> B = A -> (1 ~> B). En outre, les expressions idiomatiques intégrer les flèches les flèches et les intégrer dans les monades.

21voto

Landei Points 30509

Un bon exemple pour un constructeur de type qui n'est pas un foncteur est - Set: Vous ne pouvez pas mettre en oeuvre fmap :: (a -> b) -> f a -> f b,, parce que sans une contrainte supplémentaire Ord b vous ne pouvez pas construire f b.

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