Форум программистов, компьютерный форум, киберфорум
Haskell
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.85/13: Рейтинг темы: голосов - 13, средняя оценка - 4.85
2 / 2 / 0
Регистрация: 01.08.2015
Сообщений: 46

Применение типов

20.12.2015, 10:32. Показов 4051. Ответов 67

Студворк — интернет-сервис помощи студентам
Пытаюсь перейти от Prolog к Haskel.
Надо сделать вычисление арифметического выражения. Пишу рекурсивную программу, аналогичную Прологовской. Поскольку в списке Haskel, в отличие от Пролога, все элементы должны быть одного типа, применяю тип [String]. Приходится преобразовывать аргументы к численному представлению, а результат вычисления – обратно в символьное.
Компилятор не пропускает.
Что-то не правильно с объявлением типов или это методическая ошибка?

Haskell
1
2
3
4
5
6
7
8
9
10
11
    cc           :: (String b) => [String] -> b
    cc (a:"*":b:t) = cc(c:t)
    where c=show(read a * read b)
    cc (a:"/":b:t) = cc(c1:t)
    where c1=show(read a / read b)
    cc (a:"-":t) = show(read a - read(cc t))
    cc (a:"+":t) = show(read a + read (cc t))
    cc (a:[])    = a
    cc []    = 0
 
ERROR file:.\e3.hs:18 - Undefined class "String"
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
20.12.2015, 10:32
Ответы с готовыми решениями:

Композиция и применение
Пытаюсь как следует разобраться в обозначенных понятиях. По тексту книги вроде как всё понятно, но когда свой вариант "понимания"...

Применение обнуляемых типов в C#
Всем добрый вечер! На данный момент изучаю сей прекрасный язык и остановился на главе, посвящённой обнуляемому типу. Некоторые моменты...

Применение RAW типов
Добрый день ! В каких случаях надо применять RAW типы ? За пример буду благодарен !

67
Супер-модератор
Эксперт функциональных языков программированияЭксперт Python
 Аватар для Catstail
38228 / 21160 / 4314
Регистрация: 12.02.2012
Сообщений: 34,774
Записей в блоге: 14
20.12.2015, 14:03
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от KolodeznyDiver Посмотреть сообщение
Лексема - или символ, или число. Пустой строкой она бы не смогла стать.
- да, с этой ошибкой убедили на 70%.
Цитата Сообщение от KolodeznyDiver Посмотреть сообщение
Решая задачу вначале создаём подходящие типы,
- это да, верно
0
Антикодер
Эксперт функциональных языков программирования
1889 / 871 / 48
Регистрация: 15.09.2012
Сообщений: 3,092
20.12.2015, 14:45
не хотелось заливать в сыром виде... но раз уж такая пьянка:
axt-edsl-epsi-haskell
Там единственный исходник src/Parsing.hs
Собственно материалы(функции) взяты из статьи, на которую я давал ссылку и из курсов на edX.
Что самое интересное, статья вышла в 2007 года, а курсы edX проходят в конце 2015 года, детально не разбирался, но помоему за 8 лет парсер Эрика почти не изменился...

Надеюсь через месяц у проекта будет более приличный вид...
1
2 / 2 / 0
Регистрация: 01.08.2015
Сообщений: 46
20.12.2015, 16:09  [ТС]
calc "23-5*(6-(10+5)+10)-20+5"
"20"
По-прежнему

Добавлено через 8 минут
Какой замечательный этот Haskell!
Люди статьи про парсеры пишут, проекты делают. Есть чем заняться!
А на примитивном Прологе любой толковый студент пишет лексический анализатор за 5 минут,
а парсер арифметических выражений в лабораторной работе делает.
0
Модератор
 Аватар для Curry
5173 / 3545 / 536
Регистрация: 01.06.2013
Сообщений: 7,708
Записей в блоге: 9
20.12.2015, 16:21
Цитата Сообщение от vln1981 Посмотреть сообщение
А на примитивном Прологе любой толковый
Ключевое слово "толковый". Он и на Haskell много чего напишет. Сравнивать языки не возьмусь т.к. изучал пролог чуть-чуть в институте четверть века назад.
0
2 / 2 / 0
Регистрация: 01.08.2015
Сообщений: 46
20.12.2015, 16:22  [ТС]
Я смотрю, Хаскель располагает к глубокомыслию.
По моей программе только никто не может ничего конкретного сказать.
Там всего 9 строк.
0
Модератор
 Аватар для Curry
5173 / 3545 / 536
Регистрация: 01.06.2013
Сообщений: 7,708
Записей в блоге: 9
20.12.2015, 16:31
Цитата Сообщение от vln1981 Посмотреть сообщение
По моей программе только никто не может ничего конкретного сказать.
Программа, уж извините, демонстрирует столь низкий уровень знания языка, что Вам ответили:
Применение типов
Т.е. хотя бы начало учебника прочитать надо.
0
2 / 2 / 0
Регистрация: 01.08.2015
Сообщений: 46
20.12.2015, 17:58  [ТС]
Кто бы мне продемонстрировал среднее знание языка Haskel.
0
 Аватар для Araneo
650 / 260 / 16
Регистрация: 02.03.2014
Сообщений: 587
20.12.2015, 20:22
Посмотрел я на исходный код, и понял. Мы слишком усложняем. Там же только четыре действия и нет скобочек! Зачем мудрить.
Haskell
1
2
3
4
5
6
7
8
parse :: String -> Double
parse xs = case span (`notElem` "+-") xs of
    (y, '+':ys)     -> parse y + parse ys
    (y, '-':ys)     -> parse y - parse ys
    (y, _     )     -> case span (`notElem` "*/") y of
        (x, '*':xs) -> parse x * parse xs
        (x, '/':xs) -> parse x / parse xs
        (x, _     ) -> read x
Добавлено через 29 секунд
Haskell
1
2
> parse "2+3+3*2+2"
13.0
Добавлено через 29 секунд
Haskell
1
2
> parse "2+3+3*2+2/2"
12.0
0
1195 / 588 / 88
Регистрация: 20.09.2012
Сообщений: 1,881
20.12.2015, 20:35
Araneo, а это http://ideone.com/ZIJlvf как трактовать?
0
 Аватар для Araneo
650 / 260 / 16
Регистрация: 02.03.2014
Сообщений: 587
20.12.2015, 21:05
Как мою глупость, грешен. )) и даже понял в чём накосячил. Чай попью, придумаю как исправить.

Добавлено через 22 минуты
Haskell
1
2
3
4
5
6
7
8
9
10
parse :: Bool -> String -> Double
parse b xs = case span (`notElem` "+-") xs of
    (y, x:ys)     -> parse b y + parse (x == '+') ys
    (y, _     )     -> case span (`notElem` "*/") y of
        (x, '*':xs) -> parse b x * parse True xs
        (x, '/':xs) -> parse b x / parse True xs
        ([],_     ) -> 0
        (x, _     ) -> read x * (if b then 1 else -1)
 
calc = parse True
Пам парам, а вы ничего не видели
0
2 / 2 / 0
Регистрация: 01.08.2015
Сообщений: 46
20.12.2015, 21:22  [ТС]
Предыдущий Ваш пример хоть и неправильно, но работал.
А второй вариант совсем непонятен - что такое Bool в начале объявления?

Добавлено через 2 минуты
Тут же надо дерево строить, чтобы приоритет операций учитывать.
А у Вас просто последовательное выполнение операций.
0
Модератор
 Аватар для Curry
5173 / 3545 / 536
Регистрация: 01.06.2013
Сообщений: 7,708
Записей в блоге: 9
20.12.2015, 21:30
Цитата Сообщение от Araneo Посмотреть сообщение
Пам парам, а вы ничего не видели
calc "1/2/5"
0
 Аватар для Araneo
650 / 260 / 16
Регистрация: 02.03.2014
Сообщений: 587
20.12.2015, 21:42
Странно, вот так работает.

> calc "-2*3+3*2+2/2"
1.0

Bool - тип логических переменных.

По поводу дерева, а зачем его строить. В данном случае оно лишнее.

Добавлено через 9 минут
KolodeznyDiver, я сказал не видели )))
Haskell
1
2
3
4
5
6
7
8
9
10
11
12
13
parse :: Bool -> Bool -> String -> Double
parse b1 b2 xs = case span (`notElem` "+-") xs of
    (y, x:ys  )     -> parse b1 b2 y + parse (x == '+') True ys
    (y, _     )     -> case span (`notElem` "*/") y of
        (y, x:xs  ) -> parse b1 b2 y * parse True (x == '*') xs
        ([],_     ) -> 0
        (x, _     )
            | b1 && b2     ->        read x
            | b2           -> (-1) * read x
            | b1 && not b2 ->   1  / read x
            | otherwise    ->  -1  / read x
 
calc = parse True True
0
Модератор
 Аватар для Curry
5173 / 3545 / 536
Регистрация: 01.06.2013
Сообщений: 7,708
Записей в блоге: 9
20.12.2015, 21:50
Цитата Сообщение от Araneo Посмотреть сообщение
KolodeznyDiver, я сказал не видели
Попробуйте искать знаки операций не слева, а справа. Ибо они левоассоциативны.
0
2 / 2 / 0
Регистрация: 01.08.2015
Сообщений: 46
20.12.2015, 21:55  [ТС]
Подтверждаю, работает. Осталось скобки добавить.
Хотя и здесь ничего не понятно.
0
 Аватар для Araneo
650 / 260 / 16
Регистрация: 02.03.2014
Сообщений: 587
20.12.2015, 21:56
KolodeznyDiver, сейчас это уже вроде не нужно, работает и так, а вот если буду добавлять скобочки, то безусловно нужно будет делать как ты сказал.
0
1195 / 588 / 88
Регистрация: 20.09.2012
Сообщений: 1,881
20.12.2015, 22:09
Цитата Сообщение от Araneo Посмотреть сообщение
а вот если буду добавлять скобочки
а что? в это можно добавить скобки не переписав все с 0?
0
 Аватар для Araneo
650 / 260 / 16
Регистрация: 02.03.2014
Сообщений: 587
20.12.2015, 22:11
pycture, боюсь что нет ))
0
2 / 2 / 0
Регистрация: 01.08.2015
Сообщений: 46
20.12.2015, 22:49  [ТС]
А почему нельзя, встретив скобку,
запустить рекурсивно parse с этого места, ограничив поиск закрывающей скобкой?
0
Супер-модератор
Эксперт функциональных языков программированияЭксперт Python
 Аватар для Catstail
38228 / 21160 / 4314
Регистрация: 12.02.2012
Сообщений: 34,774
Записей в блоге: 14
21.12.2015, 11:08
Ндааа... У меня было еще две довольно подлых ошибки. Выкладываю окончательный вариант:

Haskell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
parse :: String -> String -> [String] -> [String]
parse [] lex r = if (lex /= "") then r ++ [lex] else r
parse (x:xs) lex r | ((x == '*') || (x == '/') || (x == '+') || (x == '-') || (x == '(') || (x == ')')) = 
                       if (length lex) > 0 then parse xs [] (r ++ [lex] ++ [[x]]) else parse xs [] (r ++ [[x]])
                   | otherwise = (parse xs (lex ++ [x]) r)
                   
prty :: String -> Int
prty "(" = 0
prty "+" = 1
prty "-" = 1
prty "*" = 2
prty "/" = 2
prty _   = error "!"
 
lexType :: String -> Int
lexType x | (x `elem` ["(",")","+","-","*","/"]) = 1
          | otherwise = 0
     
emptyP :: [String] -> [String] -> [[String]]
emptyP (o:os) inin@(n:ns) | (o == "(") = [os,inin]
                          | otherwise = emptyP os ((exec (head ns) n o) : (tail ns))
 
empty :: [String] -> [String] -> String
empty [] n = (head n)
empty (o:os) (n:ns) = empty os ((exec (head ns) n o) : (tail ns))                          
     
exec :: String -> String -> String -> String
exec a1 a2 "+" = show ((read a1) + (read a2))          
exec a1 a2 "-" = show ((read a1) - (read a2))          
exec a1 a2 "*" = show ((read a1) * (read a2))          
exec a1 a2 "/" = show ((read a1) `div` (read a2)) 
         
calcF :: [String] -> [String] -> [String] -> String
calcF [] s1 [] = head s1
calcF [] s1 s2 = empty s2 s1
calcF (l:ls) s1 s2 | (lexType l) == 0 = calcF ls (l:s1) s2
                   | (l == "(")       = calcF ls s1 ("(" : s2)
                   | (l == ")")       = calcF ls q1 q2
                   | (s2 == [])       = calcF ls s1 [l]
                   | (prty l) <= (prty (head s2)) = calcF (l:ls) ((exec (s1 !! 1) (s1 !! 0) (head s2)):(drop 2 s1)) (tail s2)
                   | otherwise = calcF ls s1 (l:s2)
                     where tmp=(emptyP s2 s1); q1=(tmp !! 1); q2=(tmp !! 0);
                   
calc :: String -> String
calc x = calcF (parse x "" []) [] []
 
-- Проверка
 
*Main> calc "23-5*(6-(10+5)+10)-20+5"
 
"3"
 
*Main> calc "1/2/5"
 
"0"
 
*Main> calc "2+3+3*2+2"
 
"13"
 
*Main> calc "2+3+3*2+2/2"
 
"12"
 
*Main> calc "3+100/10/2/5-4-4/2"
 
"-2"
Добавлено через 11 часов 24 минуты
KolodeznyDiver, ошибки были чисто алгоритмические:

1) при выполнении алг. операции удалялся только один операнд из стека операндов (а нужно - два);
2) при возможности выполнить операцию с более высоким приоритетом терялась проверка возможности выполнить текущую операцию.

АТД мне бы здесь не помогли...
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
21.12.2015, 11:08

Применение is_same для списка типов
Итак, std::is_same может сравнить только два типа. Написал велосипед, который сравнивает первый тип со всеми остальными. Собственно,...

Применение null-совместимых типов, проверка корня
Задание звучит так: Разработать программу, в которой определена функция вычисления квадратного корня, которая возвращает null, если корень...

Чтение и запись типов, массив типов и List<> данных в файл
Здравствуйте Подскажите способ записи и чтения любых типов данных (не компонентов) Например это: string в котором текст может быть...

Создать массивы разных типов(3 типов), вывести их на экран
Создать массивы разных типов(3 типов), вывести их на экран.

Не требуется приведение типов при умножении типов Byte
Читал тут книгу(Г. Шилдт, &quot;Полный справочник по C#&quot;), и нашел такое (ст. 77) Поскольку при умножении, например, 2 чисел типа byte,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Генератор паролей
Maks 29.10.2026
Реализация из решения ниже выполнена исключительно по моей инициативе. Самым главным критерием для меня было создание паролей, в котором отсутствуют знаки: | 1 l I Обработка содержит реквизиты: -. . .
Установка ChatGPT (Codex) на Windows без использования Microsoft Store
Fabien159 28.10.2026
Здравствуйте всем читающим! Опишу процесс установки ChatGPT (Codex) на Windows, если по каким-то причинам у вас не получается устанавить его через Microsoft Store. И так: 1. Скачиваем с. . .
Программное добавление префикса в нумерацию документов
Maks 27.10.2026
Реализация из решения ниже выполнена в самописной конфигурации на БСП (помощь начинающему коллеге). Задача: Программно добавить префикс в нумерацию документов. Решение: В модуле объекта. . .
После закрытия оутлука продолжает висеть процесс в диспетчере задач
Maks 27.10.2026
С недавнего времени в продакшене возникла проблема: при закрытии оутлука в диспетчере задач продолжал висеть процесс outlook. exe. Проблема возникла после установки MS Office 2021 LTSC на машинах, под. . .
Baragoz - DPS/HPS бот для WoW 3.3.5a, многоязычный
AmbA 26.10.2026
Хотите ещё ботов? У меня есть один! А я пока отдохну от него. https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=12062&stc=1&d=1793007952 Инструкция внутри. https:/ / youtu. be/ VpfFZSUDGnQ. . .
Особенности gif сгенерированных в Си
russiannick 21.10.2026
Рассмотрим генерацию gif файлов, которые в Си имеют свои особенности. Gif представляет собой графический формат популярный в интернете. Посмотрим на палитру. Gif файл сгенерированный в си отличается. . .
FPS контроллер с анимированными Y-Bot и 3D-звуком miniaudio (Box3D, Recast, BehaviorTree.CPP, ozz-animation, ImGui, OpenGL и SDL3)
8Observer8 18.10.2026
Содержание блога | English Version Полное мультиплатформенное руководство по стартовому проекту с FPS-контроллером игрока, анимированными роботами Y-Bot с 4-слойным блендингом, 3D-физикой Box3D,. . .
Локальный http сервер
Argus19 17.10.2026
Локальный http сервер На работе, на двух локальных компьютерах круглосуточно работают программы опроса приборов с записью в книги Excel,которые раз в сутки записываются на сервер компании. Т. к. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru