Does Haskell have a splat operator like Python and Ruby?
Asked Answered
D

3

15

In Python and Ruby (and others as well, I'm sure). you can prefix an enumerable with * ("splat") to use it as an argument list. For instance, in Python:

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

Is there something similar in Haskell? I assume it wouldn't work on lists due to their arbitrary length, but I feel that with tuples it ought to work. Here's an example of what I'd like:

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)

I'm looking for an operator (or function) that allows me to do:

ghci> f `op` tuple
3

I have seen (<*>) being called "splat", but it doesn't seem to be referring to the same thing as splat in other languages. I tried it anyway:

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
Dowland answered 14/8, 2011 at 1:13 Comment(0)
B
17

Yes, you can apply functions to tuples, using the tuple package. Check out, in particular, the uncurryN function, which handles up to 32-tuples:

Prelude Data.Tuple.Curry> (+) `uncurryN` (1, 2)
3
Bonnee answered 14/8, 2011 at 1:39 Comment(5)
I'm guessing this uses Template Haskell?Caveat
Thanks, this works a treat. Unfortunate that it looks to arbitrarily be defined only up to tuples of 15 elements, but that's probably plenty ;)Dowland
Yeah, it has to be defined for individual tuple types because in Haskell, each tuple type is technically a different type. (So (a, b), or "pair", is a completely unrelated type to (a, b, c), or "triple" -- they just have a special syntax that allows the construction of arbitrarily-large such types.) I don't think the above package is using Template Haskell, though I don't recognise the "|" symbol used in the class definition.Junkie
@mgiuca: The "|"-symbol in this context denotes a Functional Dependency.Sansen
@Chuck: There is no Template Haskell in the tuple package (though there is some custom Haskell code which emits other Haskell code as a String).Bonnee
C
3

The uncurry function turns a function on two arguments into a function on a tuple. Lists would not work in general because of their requirement for homogeneity.

Caveat answered 14/8, 2011 at 1:15 Comment(2)
Just to be clear: are you saying it can't be done on arbitrary-length tuples, but uncurry works for the special case of a pair?Dowland
@gfxmonk: Yes. Each combination of number and combination of types in a tuple is a distinct type in Haskell's type system, so a function can't take every tuple type.Caveat
H
3

No, Haskell's type system doesn't like that. Check this similar question for more details:

How do I define Lisp’s apply in Haskell?

BTW, the splat operator you talk about is also known as the apply function, commonly found on dynamical functional languages (like LISP and Javascript).

Hookup answered 14/8, 2011 at 1:32 Comment(2)
I believe this is correct for lists, but I asked specifically about tuples in the question.Dowland
@gfxmonk: Still, enumerables in Python are moe akin to lists, IMO, since they can be of arbritrary length and the splat works the same. In Haskell you can't have a function work on arbritrary tuples unless you use deep magic.Hookup

© 2022 - 2024 — McMap. All rights reserved.