与Haskell语法在if和else之间挣扎

时间:2019-09-23 23:11:30

标签: if-statement haskell syntax

当我尝试使用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设计原则的方法,那我将非常感激。

1 个答案:

答案 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