我正打算实现以下数据类型:
data Inter = Inter Double Double deriving (Read, Eq)
我实现了(+)
,(-)
,(*)
和(/)
,
但是对于此数据类型,不应重复乘幂为(^)
的整数倍。
有没有办法像我对其他人一样实现此功能?
答案 0 :(得分:2)
答案 1 :(得分:1)
考虑到(^)
的实现是一种优化,并且 会产生等效的结果,您可以做的是在与Num
相同的模块中定义更快的版本实例,并说interPower
。然后,您可以尝试添加一些重写规则,理论上应该触发这些规则,但是我建议使用-ddump-simpl-stats
编译测试程序,并确认它们确实在base
的规则执行之前就已触发:>
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
#-}
修改
只是尝试了上述方法,确实使(^)
的使用超载:
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))
使用ghc -O2 -ddump-simpl-stats -ddump-to-file
进行编译时会导致这些规则触发。参见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
...