2011-08-14 1 views
11

En python/ruby ​​(et d'autres, j'en suis sûr). vous pouvez préfixer un énumérable avec * ("splat") pour l'utiliser comme liste d'arguments. par exemple en python:Est-ce que haskell a un opérateur splat comme python/ruby?

>>> def foo(a,b): return a + b 
>>> foo(1,2) 
3 
>>> tup = (1,2) 
>>> foo(*tup) 
3 

Existe-t-il quelque chose de semblable dans le haskell? Je suppose que cela ne fonctionnerait pas sur les listes en raison de leur longueur inconnue, mais je pense que les tuples devraient fonctionner. Voici un exemple de ce que je voudrais:

ghci> let f a b = a + b 
ghci> :t f 
f :: Num a => a -> a -> a 
ghci> f 1 2 
3 
ghci> let tuple = (1,2) 

Je suis à la recherche d'un opérateur (ou fonction) qui me permet de faire:

ghci> f <op> tuple 
3 

J'ai vu < *> être appelé " splat ", mais cela ne semble pas se rapporter à la même chose que splat dans d'autres langues. Je l'ai essayé quand même:

ghci> import Control.Applicative 
ghci> f <*> tuple 

<interactive>:1:7: 
    Couldn't match expected type `b0 -> b0' 
       with actual type `(Integer, Integer)' 
    In the second argument of `(<*>)', namely `tuple' 
    In the expression: f <*> tuple 
    In an equation for `it': it = f <*> tuple 

Répondre

11

Oui, vous pouvez appliquer des fonctions aux tuples en utilisant le package tuple. Consultez, en particulier, la fonction uncurryN:

Prelude Data.Tuple.Curry> (+) `uncurryN` (1, 2) 
3 
+0

Je suppose que cela utilise le modèle Haskell? – Chuck

+0

Merci, cela fonctionne un régal. Dommage qu'il semble arbitrairement être défini seulement jusqu'à des tuples de 15 éléments, mais c'est probablement beaucoup;) – gfxmonk

+0

Ouais, il doit être défini pour les types de tuple individuels car dans Haskell, chaque type de tuple est techniquement un type différent. (Ainsi '(a, b)', ou "paire", est un type complètement indépendant de '(a, b, c)', ou "triple" - ils ont juste une syntaxe spéciale qui permet la construction arbitraire- grands types de ce genre.) Je ne pense pas que le paquet ci-dessus utilise Template Haskell, bien que je ne reconnaisse pas le "|" symbole utilisé dans la définition de classe. – mgiuca

3

La fonction uncurry transforme une fonction sur deux arguments en une fonction sur un tuple. Les listes ne fonctionneraient pas en général en raison de leur exigence d'homogénéité.

+0

Pour être clair: vous dites qu'il ne peut pas être fait sur tuples de longueur arbitraire, mais des œuvres uncurry pour le cas particulier d'une paire? – gfxmonk

+0

@gfxmonk: Oui. Chaque combinaison de nombres et de combinaisons de types dans un tuple est un type distinct dans le système de types de Haskell, donc une fonction ne peut pas prendre tous les types de tuple. – Chuck

3

Non, le système de type de Haskell ne l'aime pas. Cochez cette question similaire pour plus de détails:

How do I define Lisp’s apply in Haskell?

BTW, l'opérateur de floc vous parlez est également connu sous le nom de la fonction apply, couramment sur les langages fonctionnels dynamiques (comme LISP et Javascript).

+1

Je crois que c'est correct pour les listes, mais j'ai demandé spécifiquement au sujet des tuples dans la question. – gfxmonk

+0

@gfxmonk: Pourtant, les énumératifs en Python sont semblables aux listes, IMO, car ils peuvent être de longueur arbitraire et le splat fonctionne de la même manière. Dans Haskell, vous ne pouvez pas faire fonctionner une fonction sur des tuples arbitraires à moins d'utiliser la magie profonde. – hugomg