我编写了一个函数,它接受一个列表和一个数字,并返回一个移位反转的总和:
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,但我还是找不到办法让它发挥作用。有可能吗?
答案 0 :(得分:6)
你不能使用Complex Monad或Functor,因为那些只是按分数运算复数(注意分量乘法和复数乘法完全不同)。
考虑使用Fractional类型类:
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)