Haskell: Function to determine the arity of functions?

It's easy with OverlappingInstances: {-# LANGUAGE FlexibleInstances, OverlappingInstances #-} class Arity f where arity :: f -> Int instance Arity x where arity _ = 0 instance Arity f => Arity ((->) a f) where arity f = 1 + arity (f undefined) Upd Found problem. You need to specify non-polymorphic type for polymorphic functions: arity (foldr :: (a -> Int -> Int) -> Int -> a -> Int) Don't know how to solve this yet. Upd2 as Sjoerd Visscher commented below "you have to specify a non-polymorphic type, as the answer depends on which type you choose".

– scravy Dec 3 '11 at 17:00 2 @scravy, instance Arity x is more general than instance Arity ((->) a f). So without extensions GHC can't choose which of this two instances to use for functions. OverlappingInstances instructs GHC that a) such instances are allowed; b) she need to choose most specific one.

– max taldykin Dec 3 '11 at 17:05 Ah, thanks for the explanation. Anyways: +1; neat solution. – scravy Dec 3 '11 at 17:09 1 It makes sense that you have to specify a non-polymorphic type, as the answer depends on which type you choose, f.e.

: arity (foldr :: (a -> (Int -> Int) -> Int -> Int) -> (Int -> Int) -> a -> Int -> Int) – Sjoerd Visscher Dec 3 '11 at 17:35 3 Ok after some playing around, the solution is to add the IncoherentInstances LANGUAGE pragma ;) – is7s Dec 3 '11 at 19:15.

Yes, it can be done very, very easily: arity :: (a -> b) -> Int arity = const 1 Rationale: If it is a function, you can apply it to exactly 1 argument. Note that haskell syntax makes it impossible to apply to 0, 2 or more arguments as f a be is really (f a) b, i.e. Not f applied to a and b, but (f applied to a) applied to b.

The result may, of course, be another function that can be applied again, and so forth. Sounds stupid, but is nothing but the truth.

2 +1 for stupid truth. All Haskell functions have arity 1, because it's OK for functions to produce functions. A -> be -> c is just sugar for a -> (b -> c).

– Dan Burton Dec 3 '11 at 21:53 Maybe I shouldn't have called the function I'm looking for arity... – Frank S. Thomas Dec 3 '11 at 22:42 Alright then, is is possible to recursively find the depth of a tree of functions? – John F.

Miller Dec 5 '11 at 7:38.

But, for example, id map is identical to map, which would has arity 2 in your example. Have the following functions the same arity? F1 = (+) f2 = (\x y -> x + y) f3 x y = x + y I think your notion of "arity" is not well defined...

I mean, it's reasonable if you look at id :: a -> a. – Tarrasch Dec 3 '11 at 16:47 My definition of arity: Count the number of -> in a function's type which are not enclosed in parentheses.So the arity of id x depends on x. – Frank S.

Thomas Dec 3 '11 at 17:01 I define arity as the number of times you can apply an argument to a term. If the argument's type is not specified, use (). – FUZxxl Dec 3 '11 at 17:07.

It's not possible with standard Haskell. It may be possible using the IncoherentInstances or similar extension. But why do you want to do this?

You can't ask a function how many arguments it expects and then use this knowledge to give it precisely that number of arguments. (Unless you're using Template Haskell, in which case, yes, I expect it is possible at compile time. Are you using Template Haskell?) What's your actual problem that you're trying to solve?

3 There is no actual problem, I'm just curious. – Frank S. Thomas Dec 3 '11 at 16:56.

How about this: arity :: a -> Int arity (b->c) = 1 + arity (c) arity _ = 0.

GHCi complains: Not in scope: "b" – Frank S. Thomas Dec 5 '11 at 21:09.

In Haskell, every "function" takes exactly one argument. What looks like a "multi-argument" function is actually a function that takes one argument and returns another function which takes the rest of the arguments. So in that sense all functions have arity 1.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions