Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Haskell: postfix bang (!) for factorial?

513 views
Skip to first unread message

Stephan

unread,
Jun 1, 2005, 12:00:47 PM6/1/05
to
Anyone know of a way to get Haskell to accept a postfix operator?

I would dearly love to be able to invoke my "fac" function using a
postfixed bang.

3! = 6, 4! = 24, etc. You get the idea.

Cheers,

Stephan

Didier Verna

unread,
Jun 1, 2005, 12:10:46 PM6/1/05
to
Stephan <sla...@bellsouth.net> wrote:

> Anyone know of a way to get Haskell to accept a postfix operator?

Operator section (modulo the parenthesis) ?


(!) :: Int -> Int
(!) 1 = 1
(!) x = x * (!) (x - 1)


Main> :load /tmp/test.hs
Main> (3!)
6
Main> (6!)
720
Main>

--
Didier Verna, did...@lrde.epita.fr, http://www.lrde.epita.fr/~didier

EPITA / LRDE, 14-16 rue Voltaire Tel.+33 (1) 44 08 01 85
94276 Le Kremlin-Bicętre, France Fax.+33 (1) 53 14 59 22 did...@xemacs.org

Stephan

unread,
Jun 1, 2005, 12:14:55 PM6/1/05
to
(more details)

Here's what I have at the moment.
I use infixed bang for n-choose-k (a binary function).

e.g.

Main> 4!2
6

But I'd like to be able to invoke factorial (unary function):

Main> 4!
24

...but instead I just get:
Main> 4!
ERROR - Syntax error in expression (unexpected end of input)

This is what my Main.hs looks like:

-- Factorial
fac n = product [1..n]

-- n Choose k
choo n k = div (fac n) ((fac k) * (fac (n - k)))

infixr 5 !
(!) :: Int -> Int -> Int
x ! y = choo x y

-- I tried adding a pattern match (line #16):
13 infixr 5 !
14 (!) :: Int -> Int -> Int
15 x ! y = choo x y
16 x ! = x

but nooo.
Main> :l Main.hs
ERROR "Main.hs":16 - Syntax error in input (unexpected symbol "x")

Aaron Denney

unread,
Jun 1, 2005, 12:40:31 PM6/1/05
to
On 2005-06-01, Stephan <sla...@bellsouth.net> wrote:
> (more details)
>
> Here's what I have at the moment.
> I use infixed bang for n-choose-k (a binary function).
>
> e.g.
>
> Main> 4!2
> 6
>
> But I'd like to be able to invoke factorial (unary function):
>
> Main> 4!
> 24
>
> ...but instead I just get:
> Main> 4!
> ERROR - Syntax error in expression (unexpected end of input)

Yeah, you can't overload a function to have multiple types.
Factorial is Integral a => a -> a, whereas choose is
Integral a => a -> a -> a.

You could define c to be choose and use it like
n `c` k.

--
Aaron Denney
-><-

Hannah Schroeter

unread,
Jun 1, 2005, 12:50:03 PM6/1/05
to
Hello!

Didier Verna <did...@lrde.epita.fr> wrote:
>Stephan <sla...@bellsouth.net> wrote:

>> Anyone know of a way to get Haskell to accept a postfix operator?

> Operator section (modulo the parenthesis) ?

>(!) :: Int -> Int
>(!) 1 = 1
>(!) x = x * (!) (x - 1)

>Main> :load /tmp/test.hs
>Main> (3!)
>6
>Main> (6!)
>720
>Main>

ghci doesn't like it:

Prelude> let (!) :: Int -> Int; (!) 1 = 1; (!) x = x * (!) (x - 1)
Prelude> (3!)

<interactive>:1:
Couldn't match `Int' against `t -> t1'
Expected type: Int
Inferred type: t -> t1
In the definition of `it': it = (3 !)
Prelude>

I.e. ghc wants the result of an operator section to be of some type
(a -> b)

Kind regards,

Hannah.

Marcin 'Qrczak' Kowalczyk

unread,
Jun 1, 2005, 1:25:20 PM6/1/05
to
han...@schlund.de (Hannah Schroeter) writes:

> I.e. ghc wants the result of an operator section to be of some type
> (a -> b)

This is consistent with expanding (x `f`) to \y -> x `f` y rather than f x,
like (`f` y) which has to be expanded to \x -> x `f` y.

GHCI:
| Prelude> (() `undefined`) `seq` ()
| ()
| Prelude> (`undefined` ()) `seq` ()
| ()

Hugs:
| Prelude> (() `undefined`) `seq` ()
|
| Program error: {undefined}
|
| Prelude> (`undefined` ()) `seq` ()
| ()

Hugs doesn't conform to Haskell 98 here.

--
__("< Marcin Kowalczyk
\__/ qrc...@knm.org.pl
^^ http://qrnik.knm.org.pl/~qrczak/

Aaron Denney

unread,
Jun 1, 2005, 3:25:01 PM6/1/05
to
On 2005-06-01, Marcin 'Qrczak' Kowalczyk <qrc...@knm.org.pl> wrote:
> han...@schlund.de (Hannah Schroeter) writes:
>
>> I.e. ghc wants the result of an operator section to be of some type
>> (a -> b)
>
> This is consistent with expanding (x `f`) to \y -> x `f` y rather than f x,
> like (`f` y) which has to be expanded to \x -> x `f` y.

The first seems a tad more useful, though perhaps leading to more opaque
error messages when one does make a mistake.

Aaron Denney

unread,
Jun 1, 2005, 3:25:31 PM6/1/05
to


Second of course, expanding to "f x".

Stephan

unread,
Jun 1, 2005, 3:45:12 PM6/1/05
to
Good call. Thanks.

Stephan

unread,
Jun 1, 2005, 3:48:37 PM6/1/05
to
Aaron Denney wrote:
> On 2005-06-01, Stephan <sla...@bellsouth.net> wrote:
>
>>(more details)
>>
>>Here's what I have at the moment.
>>I use infixed bang for n-choose-k (a binary function).
<snip>

> Yeah, you can't overload a function to have multiple types.
> Factorial is Integral a => a -> a, whereas choose is
> Integral a => a -> a -> a.
>
> You could define c to be choose and use it like
> n `c` k.

I may take this approach. Saves having to type the parens.

0 new messages