[英]How to fix “Illegal type signature” error in Haskell
I ran into the following error in Haskell: "Type signatures are only allowed in patterns with ScopedTypeVariables" How should I re-use the defined variables. 我在Haskell中遇到了以下错误:“仅在具有ScopedTypeVariables的模式中允许类型签名”我应该如何重用已定义的变量。 Thanks in advance 提前致谢
sum :: (Double -> Double) -> (Double -> Double) -> Int ->
(Double -> Double)
sum f g n = (\x -> helper f g n x)
where
helper :: (Double -> Double) -> (Double -> Double) -> Int -> Double ->
Double
|n == 0 = 0
|mod n 2 == 1 = f(x) + helper f g n-1 f(x)
|otherwise = g(x) + helper f g n-1 g(x)
This actually looks more like a syntactical error: you never defined a function body for helper
, indeed you defined the signature of helper
, followed by guards (the | ...
part), but you should again state helper fgnx = ...
. 这实际上看起来更像是一个语法错误:您从未定义过用于helper
的函数体 ,的确定义了helper
的签名,后跟了警卫( | ...
部分),但是您应该再次声明helper fgnx = ...
Furthermore I don't think it is useful to define helper
here with a variable for f
, an g
, since these remain fixed throughout the recursion. 此外,我认为在此处用f
, g
的变量来定义helper
是没有用的,因为在整个递归过程中这些保持不变。
You can probably define the function as: 您可以将函数定义为:
sumfg :: (Double -> Double) -> (Double -> Double) -> Int -> Double -> Double
sumfg f g = helperf
where helperf 0 _ = 0
helperf i x = let fx = f x in fx + helperg (i-1) fx
helperg 0 _ = 0
helperg i x = let gx = g x in gx + helperf (i-1) gx
We here defined two "helper" functions helperf
and helperg
, helperf
will sum up fx
with helperg (i-1) (fx)
, and helperg
does the same, except that we use g
instead of f
. 我们在这里定义了两个“帮助程序”函数helperf
和helperg
, helperf
将fx
与helperg (i-1) (fx)
helperg
,并且helperg
进行相同的操作,只是我们使用g
而不是f
。 We here thus use mutual recursion to solve the problem. 因此,我们在这里使用相互递归来解决问题。
We can however solve this problem more elegantly, by making use of scanl :: (b -> a -> b) -> b -> [a] -> [b]
, take :: Int -> [a]
and sum :: Num a => [a] -> a
: 但是,通过使用scanl :: (b -> a -> b) -> b -> [a] -> [b]
,我们可以更优雅地解决此问题scanl :: (b -> a -> b) -> b -> [a] -> [b]
take :: Int -> [a]
sum :: Num a => [a] -> a
:
sumfg :: Num a => (a -> a) -> (a -> a) -> Int -> a -> a
sumfg f g n x = sum (take n (scanl (flip ($)) (f x) (cycle [g, f])))
Here we thus make an infinite list of g
and f
, like [g, f, g, f, g, f, ...]
with cycle [f, g]
. 因此,在这里,我们用cycle [f, g]
制作了g
和f
的无限列表,例如[g, f, g, f, g, f, ...]
cycle [f, g]
。 We then use scanl (flip ($))
to each time apply the accumulator to one of the functions, and yield that element. 然后,我们将scanl (flip ($))
应用于每次将累加器应用于其中一个函数,并产生该元素。 We take the first n
items of that list with take n
, and finally we use sum
to sum up these values. 我们采取的第一个n
该名单与项目take n
,最后我们使用sum
总结这些值。
For example: 例如:
Prelude> sumfg (2+) (3*) 5 1
91
Since (2+1) + (3*(2+1)) + (2+(3*(2+1))) + (3*(2+(3*(2+1)))) + (2+(3*(2+(3*(2+1)))))
is 91
. 由于(2+1) + (3*(2+1)) + (2+(3*(2+1))) + (3*(2+(3*(2+1)))) + (2+(3*(2+(3*(2+1)))))
为91
。
We also generalized the signature: we can now work with any numerical type a
, with the two functions f
and g
of type f, g :: a -> a
. 我们还对签名进行了概括:现在,我们可以使用任何数字类型a
,以及类型为f, g :: a -> a
的两个函数f
和g
f, g :: a -> a
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.