Нет оператора %
;вы, вероятно, ищете `mod`
вместо:
toBin 0 = [0]
toBin n | n `mod` 2 == 1 = ...
| n `mod` 2 == 0 = ...
Охранники позволяют выбирать между несколькими ветвями функции.В этом случае каждый ...
будет результатом toBin n
, если его соответствующее условие истинно.Чтобы добавить два списка вместе, вы можете использовать оператор ++
, а `div`
соответствует целочисленному делению:
toBin 0 = [0]
toBin n | n `mod` 2 == 1 = toBin (n `div` 2) ++ [1]
| n `mod` 2 == 0 = toBin (n `div` 2) ++ [0]
Однако с этим есть несколько проблем.Для начала он всегда начинает результат с 0
, что является избыточным;кроме того, использование ++ [1]
является медленным, поскольку необходимо пройти весь список, чтобы добавить элемент в конец;было бы лучше предварять каждый элемент по ходу, а затем отменить результат в конце.
Чтобы исправить обе эти вещи, мы разделим toBin
вверх в основную функцию и вспомогательную функцию:
toBin 0 = [0]
toBin n = reverse (helper n)
helper 0 = []
helper n | n `mod` 2 == 1 = 1 : helper (n `div` 2)
| n `mod` 2 == 0 = 0 : helper (n `div` 2)
В этой версии мы используем оператор :
, который принимает значение и список и возвращает список со значением, добавленным кначало.Мы также возвращаем пустой результат для 0 в нашем помощнике и вместо этого обрабатываем регистр 0 в toBin
, чтобы в результате не было больше 0, чем необходимо.
Мы можем упростить код helper
полностью пропустив охрану, так как мы просто снова пишем результат n `mod` 2
в правой части:
helper 0 = []
helper n = (n `mod` 2) : helper (n `div` 2)
Наконец, есть функция, которая выполняет div
и mod
водин шаг, который может быть более эффективным:
helper 0 = []
helper n = let (q,r) = n `divMod` 2 in r : helper q
В качестве дополнительного примечания, это на самом деле не преобразует десятичное число в двоичное, оно преобразует целое число в двоичное;Реализации на Haskell вряд ли будут хранить целые числа в десятичном формате, хотя они написаны и напечатаны в этом формате.Чтобы написать полное преобразование десятичного числа в двоичное, потребуется функция, которая анализирует десятичную строку в целое число.