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

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

20.12.2015, 10:32. Показов 3483. Ответов 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
Модератор
 Аватар для Curry
5160 / 3505 / 536
Регистрация: 01.06.2013
Сообщений: 7,611
Записей в блоге: 9
21.12.2015, 12:37
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Catstail Посмотреть сообщение
KolodeznyDiver, ошибки были чисто алгоритмические:
1) при выполнении алг. операции удалялся только один операнд из стека операндов (а нужно - два);
2) при возможности выполнить операцию с более высоким приоритетом терялась проверка возможности выполнить текущую операцию.
АТД мне бы здесь не помогли...
Catstail, Вы же "человек солидный и с понятиями". К чему выкладывать, одну за другой, не проверенные версии и оправдываться переводя стрелки на статическую типизацию, возможности которой почти не используете? Если, при применении этого стека нужно помнить, когда сколько требуется удалить, то, он, скорее всего, хуже подходит к задаче, нежели ADT дерево, в котором, для бинарных операндов два поля в конструкторе данных, для унарных одно. И, вообще, дереву при разборе выражений самое то - в статьях по Haskell, гуру часто используют с этими деревьями ещё и монаду Free (http://habrahabr.ru/post/254715/ , http://habrahabr.ru/post/263959/), и GADT (расширение ADT) - .
Интересна, так же, статья "Развитие пользовательских типов данных в программировании".

Не по теме:


Вообще то меня давно черти подпихивают начать в холиварах тему, типа "Зачем нужна динамическая типизация, окромя только как это, натурально, вредительство?". Но Новый Год скоро, да и адреналина для разгона сейчас нет.

2
Супер-модератор
Эксперт функциональных языков программированияЭксперт Python
 Аватар для Catstail
38204 / 21136 / 4310
Регистрация: 12.02.2012
Сообщений: 34,748
Записей в блоге: 14
21.12.2015, 13:58
Цитата Сообщение от KolodeznyDiver Посмотреть сообщение
К чему выкладывать, одну за другой, не проверенные версии
- видите ли, как известно, код, не прошедший верификацию, не может считаться правильным. Вы, к примеру, выкладываете верифицированный код? Нет? Ну, тогда и у Вас вполне могут быть ошибки. А разница между нами - только в темпераменте. Кстати, хорошим аргументом было бы (на мой взгляд), если бы Вы или какой-либо другой участник выложил бы тщательно проверенный, "политкорректный" код, который честно решал бы поставленную задачу: на входе строка с формулой в естественной нотации (т.е. со скобками и правильным приоритетом), на выходе - результат. Это и на ТС произвело бы положительное впечатление.

Цитата Сообщение от KolodeznyDiver Посмотреть сообщение
и оправдываться переводя стрелки на статическую типизацию,
- признание собственных ошибок - это, по-Вашему, оправдание? А пользу от АТД я не отрицал никогда. Просто не следует ее абсолютизировать.

Цитата Сообщение от Araneo Посмотреть сообщение
Этакий лисп, на хаскеле.
- И что Вы тут нашли "лисповского"?
0
Модератор
 Аватар для Curry
5160 / 3505 / 536
Регистрация: 01.06.2013
Сообщений: 7,611
Записей в блоге: 9
21.12.2015, 14:11
Цитата Сообщение от Catstail Посмотреть сообщение
хорошим аргументом было бы (на мой взгляд), если бы Вы
давно уж

Цитата Сообщение от Catstail Посмотреть сообщение
признание собственных ошибок - это, по-Вашему, оправдание?
Признание ошибок - это хорошо.
0
Супер-модератор
Эксперт функциональных языков программированияЭксперт Python
 Аватар для Catstail
38204 / 21136 / 4310
Регистрация: 12.02.2012
Сообщений: 34,748
Записей в блоге: 14
21.12.2015, 14:19
Я это видел. Парсер хороший. Попробую (не заглядывая к Вам, написать свой похожий).
0
 Аватар для Araneo
650 / 260 / 16
Регистрация: 02.03.2014
Сообщений: 587
21.12.2015, 17:50
Специально для pycture. Добавил скобки, сохранив код. На мой взгляд получилось весьма минималистично. Минус. Разбирает только правильные выражения, и не может сообщить, что конкретно не так.
Haskell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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 = par.filter (/= ' ')
 
par x = case span (/=')') x of
    (l, ')':xs) -> case span (/='(') (reverse l) of
        (l, '(':ys) -> par $ reverse ys ++ show (parse True True (reverse l)) ++ xs
    (l, _)      -> parse True True l
Добавлено через 52 секунды
> calc "(1+ 2-( 3+1)*2)+3-1+1"
-2.0

Добавлено через 7 минут
Посмотрел на свой код... ну что, типизация не используется, совсем. Это плохо. Но для такого мелкого куска без разницы.

Добавлено через 8 минут
Catstail, скобки в немеряных количествах, там где надо и не надо. Использование списка в качестве хранилища данных. !!0 !!1 я так и вижу как у вас в голове щелкает а вот здесь должен быть car а вот здесь cadr... обращение с типами...
P.S. Мой код, это пример рефаловского алгоритма выполненного на хаскеле, если что.
4
Супер-модератор
Эксперт функциональных языков программированияЭксперт Python
 Аватар для Catstail
38204 / 21136 / 4310
Регистрация: 12.02.2012
Сообщений: 34,748
Записей в блоге: 14
21.12.2015, 17:55
Цитата Сообщение от Araneo Посмотреть сообщение
скобки в немеряных количествах, там где надо и не надо.
- но это не от Лиспа... Честное слово! Я действительно пока "не принял душой" тонкости использования скобок в Хаскелле. !!0 и !!1 - да, сейчас бы по-другому написал. А вот про "обращение с типами", можно поподробнее?
1
 Аватар для Araneo
650 / 260 / 16
Регистрация: 02.03.2014
Сообщений: 587
21.12.2015, 17:58
А про типы, это из спектра ощущений. Скорее я так чувствую. Вон у меня самого, код вышел не сильно хаскельным.

Добавлено через 48 секунд
P.S. А от чего? Где ещё можно подцепить такую любовь к скобочкам?
0
1195 / 588 / 88
Регистрация: 20.09.2012
Сообщений: 1,881
21.12.2015, 18:15
Цитата Сообщение от Araneo Посмотреть сообщение
Специально для pycture...
а.. вставил не так
0
 Аватар для Araneo
650 / 260 / 16
Регистрация: 02.03.2014
Сообщений: 587
21.12.2015, 18:17
pycture, входная функция calc я же указал в посте

Добавлено через 34 секунды
Да, я не хороший, что меняю наименования интерфейсов, но что поделать
1
Эксперт 1С
 Аватар для Tklwegsd
845 / 608 / 211
Регистрация: 24.07.2013
Сообщений: 2,102
21.12.2015, 18:18
Цитата Сообщение от Araneo Посмотреть сообщение
Где ещё можно подцепить такую любовь к скобочкам?
"любовь" к скобочкам может быть от незнания приоритетов выполнения операций. Тогда они ставятся везде, где возникают сомнения в последовательности выполнения, чтобы уж было наверника.
1
1195 / 588 / 88
Регистрация: 20.09.2012
Сообщений: 1,881
21.12.2015, 18:21
ну ок.. хотя код все равно жуткий.
2
Супер-модератор
Эксперт функциональных языков программированияЭксперт Python
 Аватар для Catstail
38204 / 21136 / 4310
Регистрация: 12.02.2012
Сообщений: 34,748
Записей в блоге: 14
21.12.2015, 18:24
Цитата Сообщение от Araneo Посмотреть сообщение
А от чего? Где ещё можно подцепить такую любовь к скобочкам?
Это поверхностный взгляд. Лисперы не "любят" скобки. Просто в Лиспе их применение строго и просто. Сравните:

С,C++,Java,Vb,Haskell:

x=y+1 и x=(y+1) - это одно и то же.

Лисп

(x y z) и ((x y z)) - совсем не одно и то же.

Так что мой избыток скобок объясняется не лисповским происхождением, а моей нетвердой уверенностью в приоритетах операций и их лево- правой ассоциативности.

Добавлено через 36 секунд
Tklwegsd, совершенно верно!
0
 Аватар для Araneo
650 / 260 / 16
Регистрация: 02.03.2014
Сообщений: 587
21.12.2015, 18:31
pycture, а что именно в нём жуткого? Для меня это важно.

Добавлено через 5 минут
Лично меня в нём коробит, только использование строки в качестве промежуточного хранилища данных.
0
1195 / 588 / 88
Регистрация: 20.09.2012
Сообщений: 1,881
21.12.2015, 18:32
Araneo, он не читаемый, т.е. глядя на него общим взглядом не видно алгоритма - его надо расшифровывать. а в декларативных языках читаемый код должен быть "by default".
3
Модератор
 Аватар для Curry
5160 / 3505 / 536
Регистрация: 01.06.2013
Сообщений: 7,611
Записей в блоге: 9
21.12.2015, 18:39

Не по теме:

Цитата Сообщение от Catstail Посмотреть сообщение
Просто в Лиспе их применение строго и просто
:-!
Цитата Сообщение от Catstail Посмотреть сообщение
С,C++,Java,Vb,Haskell:
x=y+1 и x=(y+1) - это одно и то же.
Лисп
(x y z) и ((x y z)) - совсем не одно и то же.
Некорректное сравнение. Вот как надо!

С,C++,Java,Vb,Haskell:
x=y+1 и x=(y+1) - это одно и то же. Рабочий код.

Лисп:
x=y+1 и x=(y+1) - это одно и то же (синтаксическая ошибка). :D


Цитата Сообщение от Araneo Посмотреть сообщение
Лично меня в нём коробит, только использование строки в качестве промежуточного хранилища данных.
Так это ж, считай, такая реализация динамической типизации.
Как Вы улучшите свой калькулятор, что бы он и в степень возводил?
0
 Аватар для Araneo
650 / 260 / 16
Регистрация: 02.03.2014
Сообщений: 587
21.12.2015, 18:43
pycture, понял. Наверно я не буду его переписывать. Хоть и знаю что нужно сделать для повышения читаемости. Но как же лениво

Добавлено через 41 секунду
KolodeznyDiver, очень просто же! Сейчас будет.

Добавлено через 39 секунд
А не, не просто, нужно подумать.

Добавлено через 2 минуты
Вообще, тут рефакторингом запахло.
0
21.12.2015, 18:59

Не по теме:

Catstail, прошу прощение за оскорбление чувств верующих в Лисп. Но Вы сами его первые вставили. Знаете, ведь, как меня от него корёжит. Впредь, постараюсь игнорировать.

0
Супер-модератор
Эксперт функциональных языков программированияЭксперт Python
 Аватар для Catstail
38204 / 21136 / 4310
Регистрация: 12.02.2012
Сообщений: 34,748
Записей в блоге: 14
21.12.2015, 19:00
Цитата Сообщение от KolodeznyDiver Посмотреть сообщение
Как Вы улучшите свой калькулятор, что бы он и в степень возводил?
- я?
Вот так:

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
parse :: String -> String -> [String] -> [String]
parse [] lex r = if (lex /= "") then r ++ [lex] else r
parse (x:xs) lex r | ( x `elem` "+-*/^()") = 
                       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 "^" = 3
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)) 
exec a1 a2 "^" = show ((read a1) ^ (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 "3+4^3"
"67"
Main> calc "(3+4)^3"
"343"
Добавлено через 45 секунд
KolodeznyDiver, я не зафиксировал ничего обидного...
0
Модератор
 Аватар для Curry
5160 / 3505 / 536
Регистрация: 01.06.2013
Сообщений: 7,611
Записей в блоге: 9
21.12.2015, 19:07
Цитата Сообщение от Catstail Посмотреть сообщение
- я?
Нет, это я Araneo.

Добавлено через 5 минут
Catstail,
Haskell
1
(calc "2^3^2",2^3^2)
- сравните.
0
Супер-модератор
Эксперт функциональных языков программированияЭксперт Python
 Аватар для Catstail
38204 / 21136 / 4310
Регистрация: 12.02.2012
Сообщений: 34,748
Записей в блоге: 14
21.12.2015, 19:16
Цитата Сообщение от pycture Посмотреть сообщение
он не читаемый, т.е. глядя на него общим взглядом не видно алгоритма - его надо расшифровывать. а в декларативных языках читаемый код должен быть "by default".
- да... Я боялся это сформулировать. Мне мой код представляется хотя и более громоздким, но легче понимаемым (несмотря на скобки). Ну, свое-то всегда понятнее А лаконичность, хоть и хорошее качество, но прозрачность важнее.

Есть классическая задача: Дана переменная i. Если ее значение=1, присвоить два, а если значение = 2, то присвоить 1.

Самое короткое решение:

C
1
                i=3-i
Правильное решение:

C
1
2
3
4
5
6
7
8
 
                if (i==1) 
                  i=2;
                else 
                  if (i==2) 
                      i=1;
                  else
                      printf("Bad data!");
Как справедливо замечено, хорошее решение на декларативном языке должно быть прозрачным.

Добавлено через 4 минуты
Цитата Сообщение от KolodeznyDiver Посмотреть сообщение
сравните.
- что с чем?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
21.12.2015, 19:16
Помогаю со студенческими работами здесь

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

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
60
Ответ Создать тему
Новые блоги и статьи
[golang] Угол между стрелками часов
alhaos 12.05.2026
По заданным значениям часа и минуты необходимо определить значение меньшего угла между стрелками аналогового циферблата часов. import "math" func angleClock(hour int, minutes int) float64 { . . .
Debian 13: Установка Lazarus QT5
ВитГо 09.05.2026
Эта инструкция моя компиляция инструкций volvo https:/ / www. cyberforum. ru/ blogs/ 203668/ 10753. html и его же старой инструкции по установке Lazarus с gtk2. . .
Нейросеть на алгоритме "эстафета хвоста" как перспектива.
Hrethgir 06.05.2026
На десерт, когда запущу сервер. Статья тут https:/ / habr. com/ ru/ articles/ 1030914/ . Автор я сам, нейросеть только помогает в вопросах которые мне не известны - не знаю людей которые знали-бы. . .
Асинхронный приём данных из COM-порта
Argus19 01.05.2026
Асинхронный приём данных из COM-порта Купил на aliexpress термопринтер QR701. Он оказался странным. Поключил к Arduino Nano. Был очень удивлён. Наотрез отказывается печатать русские буквы. Чтобы. . .
попытка написать игровой сервер на C++
pyirrlicht 29.04.2026
попытка написать игровой сервер на плюсах с открытым бесконечным миром. возможно получится прикрутить интерпретатор питон для кастомизации игровой логики. что есть на текущий момент:. . .
Контроль уникальности выбранного документа-основания при изменении реквизита
Maks 28.04.2026
Алгоритм из решения ниже разработан на примере нетипового документа "ЗаявкаНаРемонтСпецтехники", разработанного в КА2. Задача: уведомлять пользователя, если указанная заявка (документ-основание). . .
Благородство как наказание
Maks 24.04.2026
У хорошего человека отношения с женщинами всегда складываются трудно. А я человек хороший. Заявляю без тени смущения, потому что гордиться тут нечем. От хорошего человека ждут соответствующего. . .
Валидация и контроль данных табличной части документа перед записью
Maks 22.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в КА2. Задача: контроль и валидация данных табличной части документа перед записью с учетом регламента компании. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru