2010-06-03 5 views
3

En Monads for natural language semantics, Chung-Chieh Shan montre comment les monades peuvent être utilisées pour donner une restitution bien uniforme des comptes standard de différents types de phénomènes de langage naturel (interrogatifs, focus, intensionality, et quantification). Il définit deux opérations de composition, A_M et A'_M, utiles à cette fin.Une signature de type inhabituelle

Le premier est simplement ap. Dans la monade powerset ap est l'application de la fonction non déterministe, ce qui est utile pour gérer la sémantique des interrogatives; dans la monade du lecteur, elle correspond à l'analyse habituelle de la composition extensionnelle;

Ceci est logique. L'opération de composition secondaire, cependant, a une signature de type qui ressemble à bizarre pour moi:

(<?>) :: (Monad m) => m (m a -> b) -> m a -> m b 

(Shan l'appelle A'_M, mais je vais l'appeler <?> ici.) La définition est ce que vous attendez de les types; elle correspond assez près à ap:

g <?> x = g >>= \h -> return $ h x 

Je pense que je peux comprendre comment cela fait ce qu'il est censé dans le contexte du papier (poignée verbes question de prise pour interrogatives, servir composition intensionnel, etc.). Ce qu'il fait n'est pas terriblement compliqué, mais c'est un peu bizarre de le voir jouer un rôle central ici, puisque ce n'est pas un idiome que j'ai vu auparavant chez Haskell.

Rien d'utile n'apparaît sur Hoogle pour m (m a -> b) -> m a -> m b ou m (a -> b) -> a -> m b.

Est-ce que ceci semble familier à n'importe qui d'autres contextes? Avez-vous déjà écrit cette fonction?

+1

'chose f = ap f. return' – yairchu

+0

J'ai été confus un moment parce que j'ai effectivement écrit un combinateur '()' non apparenté, comme 'liftA2 (\ b t e -> si b puis t else e)'. –

Répondre

6

Une partie de la raison pour laquelle cela semble étrange peut être la partie (m a -> b) - c'est en fait une restriction du type le plus polymorphe déduit pour l'implémentation donnée, et hors contexte serait absurde pour une monade. Le type le plus général ressemble à ceci:

> :t (\g x -> g >>= \h -> return $ h x) 
(\g x -> g >>= \h -> return $ h x) :: (Monad m) => m (t -> a) -> t -> m a 

Une version plus générale de ce qui peut être écrit sans utiliser monades du tout:

a'_F :: (Functor f) => f (a -> b) -> a -> f b 
a'_F g x = fmap ($ x) g 

Il ne semble pas être pertinent ici, mais un type comme f a -> b ne ressemble le second argument de l'opération de cobind sur un comonad:

(=>>) :: (Comonad w) => w a -> (w a -> b) -> w b 
+0

Ah, la version du foncteur est très claire: D –

+0

C'est une généralisation de flip (pour (r->) fonctor). – sdcvvc

+0

Ceci est '(??)' de l'objectif. ['xs ?? x = fmap ($ x) xs'] (https://hackage.haskell.org/package/lens-4.15.1/docs/Control-Lens-Lens.html#v:-63--63-) –

4

juste à jouer dans le ghci, j'ai essayé les éléments suivants:

> [length, sum, maximum, minimum, const 666] <?> [1, 2, 3] 
[3, 6, 3, 1, 666] 

> Nothing <?> Nothing 
Nothing 
> Just (maybe 0 (^2)) <?> Just 7 
49 
> Just (maybe 0 (^2)) <?> Nothing 
0 

> :m + Control.Monad.Instances 

> (((+2) >>=) <?> 3) (^) -- (3+2)^3 
125 
> (((+2) .) <?> 3) (^4) -- (3^4)+2 
83 
> ((. (+2)) <?> 3) (^4) -- (3+2)^4 
625 

Je pense que je l'ai fait par écrit la liste version spécifique de cela. De tous ces exemples, je trouve la version de liste la plus éclairante vers le cas général.

1

Cela me rappelle la loeb function:

> loeb :: Functor a => a (a x -> x) -> a x 
> loeb x = fmap (\a -> a (loeb x)) x 

loeb liens nœuds. Qu'est-ce que cela signifie est que si a est une sorte de conteneur, loeb fait un conteneur à partir d'un conteneur de règles en disant comment faire chaque élément du résultat final.

<?> est similaire mais au lieu d'appliquer les règles à son propre résultat final, il applique les règles à un autre conteneur, il n'est donc plus circulaire.

+0

Ouais c'est 'loeb f = fix (f ??)'? –

Questions connexes