[Haskell-cafe] function types as instances of Num

Greg Buchholz haskell at sleepingsquirrel.org
Thu Oct 26 13:46:24 EDT 2006


    Let's say we've got a little stack language, where you compute
things by transformations of stacks, using compositions of functions
from stacks to stacks (represented here as nested tuples). (See also
Chris Okasaki's "Techniques for Embedding Postfix Languages in Haskell"
 www.eecs.harvard.edu/~nr/ cs252r/archive/chris-okasaki/hw02.ps )

  For example, the simple program below calculates the square of 4... 

> {-# OPTIONS -fglasgow-exts #-}
>
> main = print $ test () 
> 
> test  = square . (lit 4)
> 
> lit :: Integer -> a -> (Integer,a)
> lit val stack    = (val, stack)
> 
> dup  (a, b)      = (a, (a, b))
> mult (a, (b, c)) = (b*a, c)
> square = mult . dup 

...now let's say I find that using the function "lit" to annotation
numeric literals ugly.  What I really want is something like...

> test' = square . 4 

...Seems simple enough, I'll just make an appropriate instance of Num
and I'll be able to use fromInteger...

> instance Eq   (a -> (Integer, a)) 
> instance Show (a -> (Integer, a)) 
> instance Num  (a -> (Integer, a)) where
>     fromInteger = lit

...but now when I try it, GHC complains...

    No instance for (Num (a -> (Integer, t)))
      arising from the literal `4' at final.hs:15:17
    Possible fix:
      add an instance declaration for (Num (a -> (Integer, t)))
    In the second argument of `(.)', namely `4'
    In the expression: square . 4
    In the definition of `test'': test' = square . 4

...so it seems that (a -> (Integer, t)) can't be unified with (a ->
(Integer, a)), or somesuch.  Any thoughts on how to get this to work?


Thanks,

Greg Buchholz




More information about the Haskell-Cafe mailing list