如何加入两个高阶函数?

HHC*_*HHC 0 haskell

我想解决一个动态生成的方程式.我在HackageDB中找到了一个很好的库,它可以使用Newton-Raphson方法计算近似根.但是,牛顿函数采用函数(类型签名为Num a => a - > a)作为等式.我的问题是,是否可以将功能附加在一起?例如:(不正确的语法)

join :: (a->a) ->(a->a)->(a->a)
join func1 func2 = func1+func2


For instance:
if func1 = 1+2*X+5*X^2 , func2 = 5 + 4*x + 2*x^3
then func3 = join func1 func2  
func3 is `6 + 6*x +  5*x^2 + 2*x^3?
Run Code Online (Sandbox Code Playgroud)

我正在考虑两种方法来做到这一点.因为每个小函数都是动态生成的,所以我必须将函数简化为上面的形式,然后将信息存储在数据类型中,例如:(不正确的语法)

data FuncInfo = Info [Double]    
  if 1 + 2*x + 3*x^2   ---->  Info [1,2,3]
     5 + 4*x^3         ---->  Info [5,0,0,4]
Run Code Online (Sandbox Code Playgroud)

这样添加两个数据并创建新函数应该很容易.然而,实际上这并不容易,因为动态生成的小函数实际上很难简化(一个小函数可能看起来像这样:) 10 / (1+x)^5.

我想的另一种方法是将函数附加在一起,这样就不需要进行简化,也不需要存储到新的数据类型中,例如:

func1 = 10 / (1+x) ^5
func2 =  25 / (1+x) ^9
newfunc = (10 / (1+x) ^5) + (25 / (1+x) ^9)
Run Code Online (Sandbox Code Playgroud)

gsp*_*spr 5

当然.但是,函数值必须有一个加法概念,所以我们必须限制类型的函数(Num b) => a -> b.然后你就可以做到

functionSum :: (Num b) => (a -> b) -> (a -> b) -> (a -> b)
functionSum f g x = (f x) + (g x)
Run Code Online (Sandbox Code Playgroud)

(我避免使用这个名字join,因为大多数人可能会想到这个完善的功能).

所以,例如,如果

func1 :: Double -> Double
func1 x = 1+2*x+5*x^2

func2 :: Double -> Double
func2 x = 5+4*x+2*x^3
Run Code Online (Sandbox Code Playgroud)

然后

*> :t (functionSum func1 func2)
(functionSum func1 func2) :: Double -> Double
Run Code Online (Sandbox Code Playgroud)

您似乎在问题的某些部分中指出您将多项式存储为系数列表.如果[a0, a1, a2, ...]描述多项式a0 + a1*x + ...,那么您还可以zipWith (+) list1 list2用来生成表示两个多项式之和的新系数列表.小心处理不同长度的有限列表的情况(提示:在较短的列表中添加零以匹配较长的长度).

  • 历史上`实例(Num b)=> Num(a - > b)`是不可能的,因为`Num`是`Eq`的子类.现在它是可能的,但我不一定认为这是一个好主意 - 在`Num`字段上的函数确实形成[_vector space_](http://hackage.haskell.org/packages/archive/vector-space字段上的/0.8.6/doc/html/Data-VectorSpace.html)(通过逐点加法的附加组),但是逐点乘法等操作在概念上通常没有意义,因为它破坏了基不变性矢量空间.因此,我更愿意将这两个类别分开. (4认同)