与 if 和 else 的 Haskell 语法作斗争



>我正在努力解决Haskell的语法,当我尝试使用GHCI编译脚本时收到"错误:输入'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 设计原则的方法,我将不胜感激。

你的函数中有几件事不是有效的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

最新更新