Leonardo Moraes
Leonardo Moraes

Reputation: 75

How to overload the power function (^) in haskell?

I'm tring to implement a following datatype:

data Inter = Inter Double Double deriving (Read, Eq)

and I implemented (+),(-),(*) and (/), but the potentiation to a integer power(^)should not be repeated multiplication for this datatype. Is there a way for me to implement this function just like i did to the others?

Upvotes: 2

Views: 686

Answers (2)

lehins
lehins

Reputation: 9767

Considering that your implementation of (^) will be an optimization and will produce equivalent results, what you can do is define your faster version in the same module as your Num instance and call it say interPower. Then you can try adding some rewrite rules, which in theory should fire, but I'd suggest compiling a test program with -ddump-simpl-stats and confirming that they do indeed fire before the rules from base do:

interPower :: Integral b => Inter -> b -> Inter
interPower = ...
{-# INLINABLE [1] interPower #-}

{-# RULES
"Inter^2/Int"     forall x. (x :: Inter) ^ (2 :: Int) = interPower x (2 :: Int)
"Inter^3/Int"     forall x. (x :: Inter) ^ (3 :: Int) = interPower x (3 :: Int)
"Inter^4/Int"     forall x. (x :: Inter) ^ (4 :: Int) = interPower x (4 :: Int)
"Inter^5/Int"     forall x. (x :: Inter) ^ (5 :: Int) = interPower x (5 :: Int)
"Inter^2/Integer" forall x. (x :: Inter) ^ (2 :: Integer) = interPower x (2 :: Int)
"Inter^3/Integer" forall x. (x :: Inter) ^ (3 :: Integer) = interPower x (3 :: Int)
"Inter^4/Integer" forall x. (x :: Inter) ^ (4 :: Integer) = interPower x (4 :: Int)
"Inter^5/Integer" forall x. (x :: Inter) ^ (5 :: Integer) = interPower x (5 :: Int)

"Inter^Int"       forall x y. (x :: Inter) ^ (y :: Int) = interPower x y
"Inter^Integer"   forall x y. (x :: Inter) ^ (y :: Integer) = interPower x y

  #-}

Edit

Just tried above approach and it indeed overloaded the usage of (^):

print (x ^ (2 :: Int))
print (x ^ (3 :: Int))
print (x ^ (4 :: Int))
print (x ^ (5 :: Int))
print (x ^ (6 :: Int))
print (x ^ (2 :: Integer))
print (x ^ (3 :: Integer))
print (x ^ (4 :: Integer))
print (x ^ (5 :: Integer))
print (x ^ (6 :: Integer))

resulted in these rules to fire when compiled with ghc -O2 -ddump-simpl-stats -ddump-to-file. See main.dump-simpl-stats:

...
1 Inter^2/Int
1 Inter^2/Integer
1 Inter^3/Int
1 Inter^3/Integer
1 Inter^4/Int
1 Inter^4/Integer
1 Inter^5/Int
1 Inter^5/Integer
1 Inter^Int
1 Inter^Integer
...

Upvotes: 2

talex
talex

Reputation: 20542

^ defined in prelude you can't overload it. It doesn't belong to any typeclass.

It is defined using * from Num.

See source.

Upvotes: 2

Related Questions