List Haskell列表错误
我试图迭代一个列表,将所有数字平方,然后将它们相加List Haskell列表错误,list,loops,haskell,List,Loops,Haskell,我试图迭代一个列表,将所有数字平方,然后将它们相加 sumsq (x:xs) = let total = 0 loop length(x:xs) (x:xs) total loop 0 (x:xs) = return () loop n (x:xs) total = do let sq = ((x:xs)!!n)^2 total = total + sq loop ((n-1) (x:xs) total) 但我在循环中得到了解析错误
sumsq (x:xs) =
let total = 0
loop length(x:xs) (x:xs) total
loop 0 (x:xs) = return ()
loop n (x:xs) total =
do
let
sq = ((x:xs)!!n)^2
total = total + sq
loop ((n-1) (x:xs) total)
但我在循环中得到了解析错误
。我哪里做错了
还有更好的方法吗?首先,你错过了空间!意义重大 第二,你忘记了
中的,从让。。。在
中。我们无法在
中的
中使用表示法:
sumsq (x:xs) =
let total = 0 in
loop length(x:xs) (x:xs) total
第三,您不使用x
和xs
表单(x:xs)
:
我们将长度xs
合并到一个块中。这是第四次
第五,我们有3个而不是2个循环参数:
loop 0 xs total = return total
第六,(!!)从0开始工作,但您从1开始使用它,因此(xs!!(n-1))
是正确的
第七,不需要使用monad,只需要递归。因此,摆脱return
和do
第八。您有无限递归total=total+smth
第九,我们不能将参数用作元组,因此,最终的工作结果是:
sumsq xs =
let total = 0 in
loop (length xs) xs total
loop 0 xs total = total
loop n xs total = loop (n-1) xs total1
where
sq = (xs !! (n -1)) ^2
total1 = total + sq
已更新
如果我们谈论的是复杂性,它是不好的-O(n^2)
,正如注释中提到的:对于每个元素,我们寻找这个元素。
我们可以简化循环函数并去掉n
参数:
loop [] total = total
loop (x:xs) total = loop xs total1
where
sq = x ^ 2
total1 = total + sq
以及我们编写的sumsq
函数:
sumsq xs = loop xs 0
附言。
这是一个更容易实现的函数
sumsq=sum。地图(^2)
首先,你错过了空间!意义重大
第二,你忘记了中的,从让。。。在
中。我们无法在
中的
中使用表示法:
sumsq (x:xs) =
let total = 0 in
loop length(x:xs) (x:xs) total
第三,您不使用x
和xs
表单(x:xs)
:
我们将长度xs
合并到一个块中。这是第四次
第五,我们有3个而不是2个循环参数:
loop 0 xs total = return total
第六,(!!)从0开始工作,但您从1开始使用它,因此(xs!!(n-1))
是正确的
第七,不需要使用monad,只需要递归。因此,摆脱return
和do
第八。您有无限递归total=total+smth
第九,我们不能将参数用作元组,因此,最终的工作结果是:
sumsq xs =
let total = 0 in
loop (length xs) xs total
loop 0 xs total = total
loop n xs total = loop (n-1) xs total1
where
sq = (xs !! (n -1)) ^2
total1 = total + sq
已更新
如果我们谈论的是复杂性,它是不好的-O(n^2)
,正如注释中提到的:对于每个元素,我们寻找这个元素。
我们可以简化循环函数并去掉n
参数:
loop [] total = total
loop (x:xs) total = loop xs total1
where
sq = x ^ 2
total1 = total + sq
以及我们编写的sumsq
函数:
sumsq xs = loop xs 0
附言。
这是一个更容易实现的函数
sumsq=sum。map(^2)
如果我理解正确,您只需使用map
和sum
即可:
Prelude> let myFun = sum . map (^2)
Prelude> myFun [1, 2, 3]
14
或使用折叠1
和lambda:
Prelude> let myFun' = foldl1 (\s x -> s + x^2)
Prelude> myFun' [1, 2, 3, 4]
30
如果我理解正确,您只需使用
map
和sum
即可:
Prelude> let myFun = sum . map (^2)
Prelude> myFun [1, 2, 3]
14
或使用折叠1
和lambda:
Prelude> let myFun' = foldl1 (\s x -> s + x^2)
Prelude> myFun' [1, 2, 3, 4]
30
这样的事情肯定是惯常的做法吗
sumSquared :: [Integer] -> Integer
sumSquared [] = 0
sumSquared (x:xs) = (x * x) + sumSquared xs
或者你可以用
foldr
,或者sum
和map
(比如@soon's answer)这样的方法肯定是最常用的吗
sumSquared :: [Integer] -> Integer
sumSquared [] = 0
sumSquared (x:xs) = (x * x) + sumSquared xs
或者你可以用
foldr
,或者sum
和map
(比如@soon's answer)do
比单词loop
更加缩进
除此之外,在这里您根本不需要do
(或return
),除非您可以回答以下问题:这是哪个单子的
你的代码有更多的问题。最严重的问题之一是:
你似乎不知道“模式匹配”是什么,也不知道它有什么好处。你真的很想了解它,否则你就写不出任何好的程序。do必须比单词
loop
缩进得多
除此之外,在这里您根本不需要do
(或return
),除非您可以回答以下问题:这是哪个单子的
你的代码有更多的问题。最严重的问题之一是:
你似乎不知道“模式匹配”是什么,也不知道它有什么好处。你真的很想了解它,否则你就无法编写任何好的程序。我不确定让这个风格糟糕的程序工作起来是不是一个好主意。显然,OP对模式匹配没有丝毫概念,最好让他学习,这样他就可以用惯用的方式“迭代列表”。非常感谢,但我不理解第三部分。我不能使用
(x:xs)
?此外,x
和xs
到底是什么意思?我知道他们x
是列表的头号人物,但是xs
呢?@AdegokeA,你可以,例如f(x:xs)=x+1:fxs
,但是在这种情况下你不用,所以我们写得更简单-xs
(或x
),没关系,这只是一个争论的名字,我不确定这是一个好主意,使这个可怕的风格的程序工作。显然,OP对模式匹配没有丝毫概念,最好让他学习,这样他就可以用惯用的方式“迭代列表”。非常感谢,但我不理解第三部分。我不能使用(x:xs)
?此外,x
和xs
到底是什么意思?我知道他们x
是列表的第一位,但是xs
呢?@AdegokeA,你可以,例如f(x:xs)=x+1:fxs
,但是在这个例子中你不使用,所以我们写得更简单-xs
(或者x
),没关系,它只是一个参数的名字而已。执行递归时,xs
是列表的其余部分吗?是:x
是头元素,xs
是尾列表。谢谢。执行递归时,xs
是列表的其余部分吗?是:x
是头元素,xs
是尾列表。