Is if possible to overload functions in Haskell similar to that of C++ or C# ? For example, if I want to define a function add which has multiple arity:
add x y = x + y add x y z = x + y + z
This doesn't work, the functions need to have different names. After some googling, I located the following paper by Simon Peyton Jones where he discusses similar overloading - Object-Oriented Style Overloading for Haskell ( http://research.microsoft.com/en-us/um/people/simonpj/papers/oo-haske... ). Is such overloading available in Haskell or as an extension to GHC / Hugs ?
SPJ's paper is the only reference I found - all other searches for Haskell and overloading leads to typeclass based overloading - which I don't want.
Arijit <pal_...@yahoo.co.in> writes: > Is if possible to overload functions in Haskell similar to that of C++ > or C# ? For example, if I want to define a function add which has > multiple arity:
> add x y = x + y > add x y z = x + y + z
You would have to do some fairly crazy typeclass hackery for that. As an example, see Text.Printf .
Arijit wrote: > Is if possible to overload functions in Haskell similar to that of C++ > or C# ? For example, if I want to define a function add which has > multiple arity:
> add x y = x + y > add x y z = x + y + z
Nope, and for very fundamental reasons. Take the second function, "add x y z". Since Haskell allows partial application, "add x y" would be a function of one variable (z). That, however, would overlap with your first definition of "add x y". How is the compiler supposed to figure out which is which?
Instead, you could define your function on a custom data type with several constructors: data Arities a = Two a a | Three a a a -- | more as necessary
and define then: add (Two a b) = a + b add (Three a b c) = a + b + c
(well, obviously for this example you would use "sum" instead, but you catch my drift.)
Paul Rubin <no.em...@nospam.invalid> wrote: > Arijit <pal_...@yahoo.co.in> writes: > > Is if possible to overload functions in Haskell similar to that of > > C++ or C# ? For example, if I want to define a function add which > > has multiple arity:
> > add x y = x + y > > add x y z = x + y + z
> You would have to do some fairly crazy typeclass hackery for that. As > an example, see Text.Printf .
Furthermore you just don't want to do it anyway. Using multi-arity functions has always been a hack. In Haskell you don't need them.
As Frederico suggested, use types. If you want to emulate multi-arity with different behaviours for each one, use a data structure (and consider reevaluating your concept). If you want to consume arbitrarily many items for the same computation, use lists.
Federico Zenith wrote: > Arijit wrote: >> Is if possible to overload functions in Haskell similar to that of C++ >> or C# ? For example, if I want to define a function add which has >> multiple arity:
>> add x y = x + y >> add x y z = x + y + z
> Nope, and for very fundamental reasons. Take the second function, "add x y > z". Since Haskell allows partial application, "add x y" would be a function > of one variable (z). That, however, would overlap with your first definition > of "add x y". > How is the compiler supposed to figure out which is which?
This is an interesting comment, but by turning on extensions in 'hugs -98', one can do some arity overloading, sort of:
class Add a where add :: a -> (a -> a)
instance Add Integer where add x = (+x)
instance Add (Integer -> Integer) where add f g = \x -> f x + g x
instance Show (Integer -> Integer) where show _ = "(Integer -> Integer)"
instance Eq (Integer -> Integer) where (==) = error "Eq.(Integer -> Integer): not implemented."
instance Num (Integer -> Integer) where fromInt n = \x -> fromIntegral n fromInteger n = \x -> fromIntegral n
Then in Hugs add (1 :: Integer) 3 4 and add ((\x -> x + 1) :: Integer -> Integer) 3 7 11
Ertugrul Söylemez <e...@ertes.de> writes: > Furthermore you just don't want to do it anyway. Using multi-arity > functions has always been a hack. In Haskell you don't need them.
I have to say, while I think that the implementation of Text.Printf.printf is pretty cool, I do agree that I've never been pained by such awkwardness myself because I never find myself wanting multi-arity functions.
(snip)
> If you want to consume arbitrarily many items for the same > computation, use lists.
Exactly. With various type system extensions (existential quantification at the least) helping when the list items can't all be of the same type. Though, normally, wrapping different expected types in an algebraic data type suffices.
"Mark T. B. Carroll" <Mark.Carr...@Aetion.com> writes:
> I have to say, while I think that the implementation of > Text.Printf.printf is pretty cool,
printf seems like a horrible hack, but it's very useful and I use it all the time even though it breaks very easily (requires type annotations where you don't expect to need them, etc). Generating messages like
print $ "Hello " ++ your_name ++ ", it's sure a nice day in " ++ your_city ....
is a big pain in the neck. If printf didn't exist I'd be looking for crazy schemes with existential wrappers, Template Haskell concoctions, etc.
Paul Rubin <no.em...@nospam.invalid> wrote: > "Mark T. B. Carroll" <Mark.Carr...@Aetion.com> writes: > > I have to say, while I think that the implementation of > > Text.Printf.printf is pretty cool,
> printf seems like a horrible hack, but it's very useful and I use it > all the time even though it breaks very easily (requires type > annotations where you don't expect to need them, etc). Generating > messages like
> print $ "Hello " ++ your_name ++ ", it's sure a nice day in " ++ > your_city ....
> is a big pain in the neck. If printf didn't exist I'd be looking for > crazy schemes with existential wrappers, Template Haskell concoctions, > etc.
If it's just string concatenation, I would use the most straightforward way to do it: concat.
concat [ "Hello ", yourName, ", it's sure a nice day in ", yourCity, ...]
If your format is complicated, printf won't help anyway. In such cases a Writer monad comes in handy:
import MonadLib
formatIRC :: WriterM m String => Maybe String -> String -> [String] -> m () formatIRC prefix command args = do case prefix of Just pfx -> put ":" >> put pfx >> put " " Nothing -> return () put command forM_ args $ \arg -> do put " " when (' ' `elem` arg) $ put ":" put arg
Printf is really only useful where you want to format numbers and it's probably best to limit its use to that.
On Jan 28, 6:19 am, Federico Zenith <non.mi...@mma.re> wrote:
> Arijit wrote: > > Is if possible to overload functions in Haskell similar to that of C++ > > or C# ? For example, if I want to define a function add which has > > multiple arity:
> > add x y = x + y > > add x y z = x + y + z
> Nope, and for very fundamental reasons. Take the second function, "add x y > z". Since Haskell allows partial application, "add x y" would be a function > of one variable (z). That, however, would overlap with your first definition > of "add x y". > How is the compiler supposed to figure out which is which?
[snip]
Thanks for your reply. I understand the difficulty associated with multiple arity functions in Haskell 98. However the paper by SPJ I linked to specifically talks about extending the language to allow for such overloading. And that paper is a few years old. I was wondering if the extension discussed in the paper been incorporated into the language / available as a GHC extension. My belief was such an extension would be available, given 1) the plethora of extensions that exist for haskell, 2) the usefulness of the feature and 3) the feature was conceived by SPJ few years back - enough time for an implementation.
I have seen implementations of a multiple arity zip function using template haskell, but I believe you need to specify the arity explicitly - no automatic inference. But documentation on template haskell is very scarce - the only good reference I was able to locate is SPJ's original paper.
Arijit <pal_...@yahoo.co.in> wrote: > On Jan 28, 6:19 am, Federico Zenith <non.mi...@mma.re> wrote: >> Arijit wrote: >>> Is if possible to overload functions in Haskell similar to that of C++ >>> or C# ? For example, if I want to define a function add which has >>> multiple arity:
>> > add x y = x + y >> > add x y z = x + y + z > Thanks for your reply. I understand the difficulty associated with > multiple arity functions in Haskell 98. However the paper by SPJ I > linked to specifically talks about extending the language to allow for > such overloading.
I have only skimmed the paper, but unless I'm mistaken, it looks like the paper is dealing with OO-style overloading of methods (i.e., a fixed number of signatures, possibly with different arity), not with declaring functions of arbitrary (indefinite) arity.
Maybe an actual demonstration will make things clearer. For simplicity, we'll restrict to Integers:
{-# LANGUAGE FlexibleInstances #-}
class AddType r where add' :: [Integer] -> r
instance AddType Integer where add' args = sum args
instance AddType r => AddType (Integer -> r) where add' args = \a -> add' (a:args)
and so on. But as others have said, this is ugly as hell, it's annoying because you have to be very careful with the types and might need to add annotations, and in this particular case it's much better to use just "sum [2,3]" and "sum [2,3,4]" instead.
This technique has its uses for border cases like "printf", but even then the error messages can be cryptic if you make a mistake.
So, if you really just want to define a functions "add" with arbitrary arity: Don't. If you would like to so something else: Maybe, depending on what it actually is.
> And that paper is a few years old. I was wondering if the extension > discussed in the paper been incorporated into the language / > available as a GHC extension.
Overlapping instances have been incorporated. Closed classes/method constraints have not, AFAIK, and my gut feeling is that at some point they may become problematic (which is maybe the reason they haven't been added).