在 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)