当我尝试使用GHCI编译脚本时,我在Haskell的语法中苦苦挣扎,并收到“错误:在输入'if'上解析错误”的信息。我的代码的目的是返回无序列表的最小值和最大值。它通过将列表分为两半并找到每一半的最小值和最大值来递归地执行此操作。如果列表只有一个元素,则仅返回该元素既是最大值又是最小值,如果列表具有两个元素,则将进行简单比较以找到最小值和最大值。这是我的代码,“ splitlist”功能来自在线资源:
splitlist :: [a] -> ([a], [a])
splitlist xs = splitAt ((length xs + 1) `div` 2) xs
minMax :: [Int] -> [Int]
minMax x
if length x == 1 then
[x, x]
else if length x == 2 then
if (head x > tail x) then
[tail x, head x]
else
[head x, tail x]
else
listOfLists = splitlist x
list1 = listOfLists!!0
list2 = listOfLists!!1
minMax1 = minMax list1
minMax2 = minMax list2
if (minMax1!!0 < minMax2!!0) then
min = minMax1!!0
else
min = minMax2!!0
if (minMax!!1 > minMax2!!1) then
max = minMax1!!1
else
max = minMax2!!1
[min, max]
我也很怀疑我没有尝试按照Haskell的意图进行此操作,我是一个初学者,仍然不小心将其像python一样对待了很多。理想情况下,如果有人可以告诉我我的方法做错了什么,然后向我展示一种更符合Haskell设计原则的方法,那我将非常感激。
答案 0 :(得分:4)
您的函数中有几处无效的Haskell语法。您缺少=
,并且您正在尝试以Haskell不允许的方式声明变量。
我试图重新排列您的代码以使其正确,这就是我得到的:
splitlist :: [a] -> ([a], [a])
splitlist xs = splitAt ((length xs + 1) `div` 2) xs
minMax :: [Int] -> [Int]
minMax x = if length x == 1 then
[head x, head x]
else if length x == 2 then
if (head x > (head $ tail x)) then
[(head $ tail x), head x]
else
[head x, (head $ tail x)]
else [if (minMax1!!0 < minMax2!!0) then minMax1!!0 else minMax2!!0,
if (minMax1!!1 > minMax2!!1) then minMax1!!1 else minMax2!!1]
where
listOfLists = splitlist x
list1 = fst listOfLists
list2 = snd listOfLists
minMax1 = minMax list1
minMax2 = minMax list2
您的算法似乎按预期工作!这有点棘手,因为通常这不是大多数人倾向于编写Haskell方法的方式。
这里是一个不同的实现,可能对比较有用:
minMax :: [Int] -> [Int]
minMax [] = []
minMax (x:xs) = minMax' x x xs
where
minMax' a b [] = [a, b]
minMax' a b (x:xs) = minMax' (min a x) (max b x) xs