Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell:分析错误可能是缩进不正确或括号不匹配_Haskell - Fatal编程技术网

Haskell:分析错误可能是缩进不正确或括号不匹配

Haskell:分析错误可能是缩进不正确或括号不匹配,haskell,Haskell,当我尝试使用下面的函数来实现下面的函数时,编译器返回 分析错误(可能缩进不正确或括号不匹配) 职能: demo :: Int -> [a] -> [a] demo arg [] = [] demo arg (x:xs) = demo' arg 0 (x:xs) -- n = 0 where demo' :: Int -> Int -> [a] -> [a] demo' arg n l = if arg <= leng

当我尝试使用下面的函数来实现下面的函数时,编译器返回

分析错误(可能缩进不正确或括号不匹配)

职能:

demo :: Int -> [a] -> [a]
demo arg [] = [] 
demo arg (x:xs) = demo' arg 0 (x:xs) -- n = 0
    where 
        demo' :: Int -> Int -> [a] -> [a]
        demo' arg n l = if arg <= length l 
                        then take arg l 
                        else 
                            -- call demo' with new parameters:
                            -- (x:xs) = (x:xs) ++ [(x:xs)!!n]
                            -- arg = arg - 1
                            -- n = n + 1 
                            demo' (arg-1) (n+1) ((x:xs) ++ [(x:xs)!!n]) ```
演示8[1,2,3]应返回[1,2,3,1,2,3,1,2]

demo::Int->[a]->[a]
设n=0
演示参数[]=[]
演示参数(x:xs)=

如果arg您无法在顶层写入
让n=0
。一旦删除它,代码的
else let
部分也不会正确缩进,因为它的用法(在
do
块之外)总是
let。。。在…
中,
let
部分的内容必须相等缩进。即使它是格式化的,
let
也是递归的,因此
arg=arg-1
表示一个比它本身小一的值,它不会计算

现在,这个函数实际上做了两件事:它循环遍历列表中的所有元素,并将其限制在给定的长度内。标准库中已经提供了这两个选项

demo n xs = take n (cycle xs)
如果你想自己写,类似的细分也是合理的

demo :: Int -> [a] -> [a]
-- Handle negative n, so we can assume it's positive below
demo n _ | n < 0 = []
-- Similarly, handle empty list, so we can assume it's non-empty below
demo _ [] = []
-- Given a positive n and non-empty list, start cycling list with limit n.
demo n list = demo' n list
  where
    -- Limit has been reached, stop.
    demo' 0 _ = []
    -- List is exhausted, cycle back to the start.
    demo' m [] = demo' m list
    -- Take the next element of the list and continue.
    demo' m (x:xs) = x : demo' (m-1) xs
demo::Int->[a]->[a]
--处理负n,所以我们可以假设它在下面是正的
演示n | n<0=[]
--类似地,处理空列表,所以我们可以假设它在下面是非空的
演示[]=[]
--给定一个正n和非空列表,开始循环限制为n的列表。
演示n列表=演示n列表
哪里
--已达到极限,停止。
演示“0”
--列表已用尽,循环回到开始。
演示'm[]=演示'm列表
--获取列表中的下一个元素并继续。
演示'm(x:xs)=x:demo'(m-1)xs

请注意,不必使用
长度
,这是一件好事<代码>长度
在无限列表上发散,而这将优雅地处理它们。

您正在混合命令式和函数式范例:
let n=0
let(x:xs)=(x:xs)+(x:xs)!!n
arg=arg-1
n=n+1
是(在代码中)命令式表达式。您希望修改
n
(x:xs)
arg
的值,但函数式编程的工作方式并非如此

您声明的函数是纯函数:这意味着您不能期望值被修改(我们称之为“副作用”)。你唯一能做的就是用新参数调用一个新函数(或同一个函数),新参数是从原始参数“动态”计算出来的

让我们尽量具体点

你不能这样做:

arg = arg - 1
demo arg (x:xs)
但你可以做到:

demo (arg - 1) (x:xs)
后者是调用
demo
,参数为
arg-1
。从未修改过
arg
的值

代码中的主要问题是
n
变量。它在第一次调用时应该是
0
,并且应该在每次
arg
时增加,以将
(x:xs)
中的下一个元素添加到
(x:xs)
本身的末尾。因此,列表将以循环的方式增长,直到我们能够获得所需数量的元素

为了达到这个目标,您必须创建一个辅助函数,并将递归“移动”到该辅助函数中:

demo :: Int -> [a] -> [a]
demo arg [] = [] 
demo arg (x:xs) = demo' arg 0 (x:xs) -- n = 0
    where 
        demo' :: Int -> Int -> [a] -> [a]
        demo' arg n l = if arg <= length l 
                        then take arg l 
                        else 
                            -- call demo' with new parameters:
                            -- (x:xs) = (x:xs) ++ [(x:xs)!!n]
                            -- arg = arg - 1
                            -- n = n + 1 
                            demo' (arg-1) (n+1) ((x:xs) ++ [(x:xs)!!n]) ```

有一种更好的方法来实现这一点(
demo n=take n.cycle
),但我试图保持与原始实现接近。

可能存在不正确的缩进。
let..in
块看起来缩进不正确。尝试对其缩进进行实验,以获得要编译的代码。
let arg=arg-1
let n=n+1
是递归定义,它们将
arg
n
定义为无限循环计算。你不会想要的。您正在尝试在Haskell中对变量进行变异,而Haskell的设计就是为了让这变得不可能。这种方法在FP语言中太过必要。粗略地说,“更改”变量的唯一方法是使用新值调用函数,例如
f0=0;fn=f(n-1)
定义了一个递归,它“减少”
n
直到它达到0。谢谢jferard!你的代码正是我的意思。我认为问题是由变量n引起的,但我不知道如何解决,谢谢你回答我的问题。@Sean,不客气。你要么接受我的答案,要么接受伊弗米特的答案。
demo :: Int -> [a] -> [a]
demo arg [] = [] 
demo arg l = demo' arg 0 l
    where 
        demo' :: Int -> Int -> [a] -> [a]
        demo' arg n l = if arg <= length l 
                        then take arg l 
                        else demo' arg (n+1) (l ++ [l!!n])