len*_*den -1 haskell functional-programming
我想为我的自定义数据类型实现幂函数。我的意思是具有以下签名的功率 (^):
(^) :: (Num a, Integral b) => a -> b -> a
Run Code Online (Sandbox Code Playgroud)
我的意思是我的数据类型MyData应该是 instance of Num,所以我可以写
x :: MyData
...
y = x ^ b
Run Code Online (Sandbox Code Playgroud)
其中 b 是一些Integral。当我们需要一个类的功能时,这很容易
(+), (-), (*) :: (Num a) => a -> a -> a
Run Code Online (Sandbox Code Playgroud)
我们只是写
instance Num MyData where
(*) x y = someFunc x y
Run Code Online (Sandbox Code Playgroud)
但我不知道如何定义它,因为还有Integral b. 这种语法应该是这样的
instance (Integral b) => Num MyData b where
(^) x y = someFunc x y
Run Code Online (Sandbox Code Playgroud)
但是我已经尝试了一百种这样的变体,但没有任何效果。数小时的谷歌搜索也无济于事。
你不必(^)为你的数据类型做任何定义;如果你的类型有一个Num实例,你可以x ^ b免费获得,因为它(^)是为具有实例的任何类型定义的Num。(它基本上只是调用*了很多。)
请注意,(^)它不是Numor的成员Integral;它只是一个独立的函数,其类型受两个类的约束。
来自https://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.Real.html#%5E
(^) :: (Num a, Integral b) => a -> b -> a
x0 ^ y0 | y0 < 0 = errorWithoutStackTrace "Negative exponent"
| y0 == 0 = 1
| otherwise = f x0 y0
where -- f : x0 ^ y0 = x ^ y
f x y | even y = f (x * x) (y `quot` 2)
| y == 1 = x
| otherwise = g (x * x) (y `quot` 2) x -- See Note [Half of y - 1]
-- g : x0 ^ y0 = (x ^ y) * z
g x y z | even y = g (x * x) (y `quot` 2) z
| y == 1 = x * z
| otherwise = g (x * x) (y `quot` 2) (x * z) -- See Note [Half of y - 1]
Run Code Online (Sandbox Code Playgroud)
x0是你的MyData价值;唯一(^)能做的事情x0(因为它被作为x参数传递给for g)是将它自身相乘,所以(^)只要你(*)在你的Num实例中定义,技术上就可以工作。