Борьба с синтаксисом Haskell с if и else - PullRequest
1 голос
/ 24 сентября 2019

Я борюсь с синтаксисом Haskell и получаю "error: parse error on input 'if'", когда пытаюсь скомпилировать свой скрипт с GHCI.Цель моего кода - вернуть минимум и максимум неупорядоченного списка.Он делает это рекурсивно, разделяя список пополам и находя минимум и максимум каждой половины.Если список имеет только один элемент, он просто возвращает этот элемент как максимум и минимум, если список содержит два элемента, он делает простое сравнение, чтобы найти минимум и максимум.Вот мой код, функция «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, яновичок и все еще случайно относиться к нему как к питону довольно часто.В идеале, если бы кто-то мог сказать мне, что я делаю не так с моим методом, а затем показать мне метод, более соответствующий принципам проектирования Haskell, я был бы очень признателен.

1 Ответ

4 голосов
/ 24 сентября 2019

В вашей функции есть несколько вещей, которые не соответствуют синтаксису 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...