在 Haskell 中将函数从实数提升为复数
Lifting a function from real numbers to complex numbers in Haskell
我写了一个函数,它接受一个列表和一个数字,returns 一个逆移位的总和:
sumInvZ::[Float]->Float->Float
sumInvZ zList z = let invList = [if z==x then 0 else 1/(z-x)|x<-zList] in foldr (+) 0 invList
我想将此函数泛化为也作用于复数。一个简单的解决方案就是重写它:
import Data.Complex
sumInvZC::[Complex Float]->Complex Float->Complex Float
sumInvZC zList z = let invList = [if z==x then 0 else 1/(z-x)|x<-zList] in foldr (+) 0 invList
但我也有兴趣使用 Complex monad 直接提升我的 SumInvZ。我玩过 liftM 的各种变体,但我一直无法找到让它工作的方法。有可能吗?
您不能为此使用 Complex Monad 或 Functor,因为它们只是按分量对复数进行运算(请注意,按分量乘法和复数乘法是完全不同的东西)。
考虑使用小数类型类:
sumInvZ :: (Fractional f, Eq f) => [f] -> f -> f
sumInvZ zList z = let invList = [if z==x then 0 else 1/(z-x)|x<-zList] in
foldr (+) 0 invList
顺便说一句,您可以以更具可读性的方式重写该函数:
sumInvZ :: (Fractional f, Eq f) => [f] -> f -> f
sumInvZ zList z = sum [if z==x then 0 else 1/(z-x) | x <- zList]
同时考虑@leftaroundabout 建议的两个变体:
sumInvZ zList z = sum [1/(z-x) | x<-zList, x/=z]
或者,交换参数,
sumInvZ z = sum . map (recip . (z-)) . filter (/=z)
我写了一个函数,它接受一个列表和一个数字,returns 一个逆移位的总和:
sumInvZ::[Float]->Float->Float
sumInvZ zList z = let invList = [if z==x then 0 else 1/(z-x)|x<-zList] in foldr (+) 0 invList
我想将此函数泛化为也作用于复数。一个简单的解决方案就是重写它:
import Data.Complex
sumInvZC::[Complex Float]->Complex Float->Complex Float
sumInvZC zList z = let invList = [if z==x then 0 else 1/(z-x)|x<-zList] in foldr (+) 0 invList
但我也有兴趣使用 Complex monad 直接提升我的 SumInvZ。我玩过 liftM 的各种变体,但我一直无法找到让它工作的方法。有可能吗?
您不能为此使用 Complex Monad 或 Functor,因为它们只是按分量对复数进行运算(请注意,按分量乘法和复数乘法是完全不同的东西)。
考虑使用小数类型类:
sumInvZ :: (Fractional f, Eq f) => [f] -> f -> f
sumInvZ zList z = let invList = [if z==x then 0 else 1/(z-x)|x<-zList] in
foldr (+) 0 invList
顺便说一句,您可以以更具可读性的方式重写该函数:
sumInvZ :: (Fractional f, Eq f) => [f] -> f -> f
sumInvZ zList z = sum [if z==x then 0 else 1/(z-x) | x <- zList]
同时考虑@leftaroundabout 建议的两个变体:
sumInvZ zList z = sum [1/(z-x) | x<-zList, x/=z]
或者,交换参数,
sumInvZ z = sum . map (recip . (z-)) . filter (/=z)