Reputation: 75
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
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