我编写了这样的代码,但编译时声称“xx不在范围内”时出错。为什么我会得到这个haskell代码的“xx不在范围错误”?
test x =
let xx = 2 * x
in result
where result = replicate xx 3
我知道我可以通过使用in replicate xx 3
解决这个问题,但是,上面的代码只是一个演示,我处理的实际代码如下所示:
nthElement :: (Ord b)=>(a->b)->Int->[a]->[a]
nthElement _ _ [] = []
nthElement _ _ [x] = [x]
nthElement op k [email protected](x:xs)
| k > (length vals) = vals
| otherwise = let left = [p | p<-vals, (op p) < (op x)]
midd = [p | p<-vals, (op p) == (op x)]
right = [p | p<-vals, (op p) > (op x)]
leftLen = length left
middLen = length midd
in result where result | leftLen >= k = (nthElement op k left) ++ midd ++ right
| (leftLen + middLen) >= k = left ++ midd ++ right
| otherwise = left ++ midd ++ nthElement op (k-middLen-leftLen) right
看来,如果我不“T使用where
条款,我不得不使用深度嵌套的,如果是这样的:
nthElement :: (Ord b)=>(a->b)->Int->[a]->[a]
nthElement _ _ [] = []
nthElement _ _ [x] = [x]
nthElement op k [email protected](x:xs)
| k > (length vals) = vals
| otherwise = let left = [p | p<-vals, (op p) < (op x)]
midd = [p | p<-vals, (op p) == (op x)]
right = [p | p<-vals, (op p) > (op x)]
leftLen = length left
middLen = length midd
in if leftLen >= k
then (nthElement op k left) ++ midd ++ right
else if (leftLen + middLen) >= k
then left ++ midd ++ right
else left ++ midd ++ nthElement op (k-middLen-leftLen) right
所以,我怎么会改变我的代码来修复错误编译以及使用嵌套如果avoide?
把它看作是{{xx = 2 * x in result}其中{result = replicate xx 3}''。大括号显示范围。你可以做'let {xx = 2 * x;结果=复制xx 3}结果中,无论如何都会更容易阅读。 – bheklilr
在[haskellWiki](https://wiki.haskell.org/Let_vs._Where)上有一篇非常好的文章解释 – Carsten
@bheklilr你应该让它成为答案,因为它是问题的答案(标题在laest)。 – mb14