Программирование

Ответить в тред Ответить в тред
Check this out!
Haskell тред /haskell/ Аноним 14/12/20 Пнд 14:59:05 18802251
istoriya-yazyko[...].png 53Кб, 992x693
992x693
14/12/20 Пнд 15:05:34 18802282
>>1880225 (OP)
Не прошло и года... А нет, прошло.
Аноним 14/12/20 Пнд 15:06:23 18802293
Аноны, которые прогают реальный хачкель-код за деньги, что вы используете, Free monads(church-encoded) или Tagless final?
Почему? Какие подводные камни?
Аноним 14/12/20 Пнд 20:01:37 18805204
>>1880229
newtype App a = App { runApp :: ReaderT AppCtx IO }
Аноним 15/12/20 Втр 00:47:18 18807875
>>1880520
И этого хватает?
Всё в один эффект пихать? А как же клепание DSL-ек и прочие сексуальные вещи? :o
Аноним 15/12/20 Втр 01:09:23 18808016
>>1880787
Нахуй ненужон ваш DSL в обычном приложении.
Но если ты пишешь либу то можно взять mtl.
Аноним 15/12/20 Втр 03:37:00 18808647
>>1880229
>реальный хачкель-код за деньги
Ну ты насмешил.
Недавно поковыривал некоторые библиотеки: всё, в чём увлеклись фри монадами, скатилось в нечитаемое перловое говно. Не представляю, как это кто-то поддерживает.
Теглесс нигде не видел.
Как написал анон выше, хочешь сделоть приложение - используй трансформеры.
Аноним 15/12/20 Втр 08:57:43 18809368
>>1880864
>> скатилось в нечитаемое перловое говно
Ты точно фри монады ни с чем не путаешь?
>> используй трансформеры
Так это же и есть теглесс.
Аноним 15/12/20 Втр 23:06:29 18815189
>>1880520
>>1880864
А как хачкель-погромисты в живой природе относятся к умеренному point-free, наподобие:
hasNoRepeats = (==) <> nub
Или
someMathStuff = liftM4 (,,,) (+2) (
3) (`div` 10) (^7)
?
Аноним 15/12/20 Втр 23:33:04 188155710
Аноним 16/12/20 Срд 08:21:06 188165411
Аноним 16/12/20 Срд 09:10:24 188168212
>>1881518
> (==) <> nub
(==) <*> nub
утренний фикс на свежую голову
Аноним 27/12/20 Вск 20:58:47 189275213
Как в хаскелле описать тип "Строка, которая которая соответсвует шаблону Pattern"?
Аноним 28/12/20 Пнд 14:20:46 189347914
>>1892752
Смотря что такое строка и паттерн
Аноним 28/12/20 Пнд 22:02:50 189400615
>>1893479
String - последовательность объектов типа Char.
Pattern - пердикат, проверяющий строку на некоторые требования (которые определяют семантику паттерна).
Аноним 28/12/20 Пнд 23:22:45 189407016
>>1894006
Осталось понять что такое тип
Аноним 30/12/20 Срд 20:06:19 189603217
Есть тип: MidiNote - целое число от 0 до 255.
Есть операции сложения и вычитания над этим типом.

Как выразить этот тип в хаскелле? Естсетвенно все ошибки, связанные с несоответствием типа, должны быть в компил-тайме.
Аноним 30/12/20 Срд 20:42:48 189606718
>>1896032
>Как выразить этот тип в хаскелле
data MidiNote = One | Two | Three ... TwoHundyredFiftiFive
Аноним 30/12/20 Срд 21:40:51 189614219
>>1896067
Ебать. А иначе никак? Типа
data Midi = Range(0,255)
Аноним 30/12/20 Срд 22:21:11 189617120
>>1896142
Ну вопрос был "как выразить этот тип". Типы в хаскелле представляют из себя структуру нихуёв, которые начинают что-то делать с момента бинда к ffi
Можешь использовать Int8 (-127|128) из Data.Int или Word8 из Data.Word
import Data.Word
let myFiveInEightBitBound = 5 :: Word8

При аут оф баунде вроде-как всё пойдёт с нуля, как в сях
Аноним 08/01/21 Птн 01:23:08 190421121
>>1892752
Если втупую, то можно используя умные конструкторы.
Например, сделаем такой модуль:

module Satisfy (Pattern(..), Satisfy, satisfy) where
import Data.Proxy(Proxy(..))

class Pattern p a where
tryMatch :: Proxy p -> a -> Bool

data Satisfy a pat where
Satisfy :: Pattern pat a => a -> Satisfy a pat
satisfy :: forall pat a. Pattern pat a => a -> Maybe (Satisfy a pat)
satisfy x
|tryMatch (Proxy @pat) x = Just (Satisfy x)
|otherwise = Nothing
Теперь можем использовать его в других модулях:

data LengthMoreThan5 = LengthMoreThan5
instance Pattern LengthMoreThan5 String where
tryMatch _ s = length s > 5

test1 = satisfy @LengthMoreThan5 "querty" -- Just (Satisfy "querty")
test2 = satisfy @LengthMoreThan5 "qu" -- Nothing
Аноним 08/01/21 Птн 01:34:23 190421922
Аноним 08/01/21 Птн 01:42:56 190422423
>>1904219
Це пиздось якиста
Как будто высиралось специально, чтобы показать хаскель с убогой стороны
Аноним 08/01/21 Птн 02:14:33 190423324
>>1904224
ВНЕЗАПНО, возможность делать вещи, для которых язык не предназначен.
Вся эта мишура - это уже про зависимые типы. Хочется красоты в этом - надо брать не хаскель, а идрис какой-нибудь.
Аноним 08/01/21 Птн 02:44:04 190424025
>>1904233
> Хочется красоты в этом - надо брать не хаскель, а идрис какой-нибудь.
Или пролог с лиспом. В них тоже реализовать зависимые типы в компил-тайме - задача не сложная.
Аноним 08/01/21 Птн 03:00:04 190424126
>>1904240
В хаскеле нет типов
Аноним 08/01/21 Птн 05:58:07 190428727
Аноним 08/01/21 Птн 12:51:07 190437728
>>1904241
В хаскелле есть система типов, правда слабая. Линейных типов нет, зависимых типов нет. Но система типов хаскелля в любом случае лучше, чем во всяких сях, нимах, джавах.
Аноним 18/01/21 Пнд 02:45:30 191376729
978-1-4612-9839[...].jpg 29Кб, 306x477
306x477
>>1880225 (OP)
А вы действительно всерьёз пытаетесь читать Маклейна? Зачем?
Аноним 18/01/21 Пнд 05:43:34 191380930
>>1913767
Не представляю чем там может заниматься математик
Теория категорий большее отношение имеет к компьютерной лингвистике чем математике
Аноним 18/01/21 Пнд 09:11:41 191386231
>>1913809
Теория категорий - это не только базовые определения понятий вроде "функтор" и "естественное преобразование".
Аноним 19/01/21 Втр 00:43:15 191469232
>>1880229
Во-первых, на Хаскеле за деньги никто не пишет. Вообще, все нормальные люди наоборот донатят на развитие Хаскеля, потому что приколоться за язык хочется, но самому его развивать по понятным причинам лень. Воспринимай Хаскель как сорт оф сообщества стримеров, которые производят интересный контент. Если ты сам хочешь стать стримером.. ну я не знаю.. можно, конечно, но, наверное, надо к этому какую-то предрасположенность иметь.

Теперь, про free и tagless final.

Tagless final в хаскелевкой интерпретации - это что-то вроде абстрагирования по эффекту : f :: (MyConstraint F) a -> F b. Там внутри обычно unwrapped state co-density, которая инлайнится и даёт хорошую производительность. Практически, линейный код на CPS получаешь. Хорошо для всяких парсеров с мелкими функциями, которые будут заинлайнены. Почти стандарт для хаскельлиб.

Free - это интерпретатор. И жесткий DSL. Иногда он красивее, чем tagless final (https://docs.google.com/presentation/d/1VhS8ySgk2w5RoN_l_Ar_axcE4Dzf97zLw1uuzUJQbCo/edit#slide=id.g575348a5eb_0_0). На синтетике медленнее, но в реальной программе всё обстоит сложнее. Все инлайнинги tagless final тоже рано или поздно ломаются, поэтому есть варик забить на них с самого начала и идти по пути free. Ребята, которые бенчмаркают крупные либы (типа Snoyman-а) пишут, что реальной разницы они уже не видят.

Мой совет - вообще не лезть в абстракции, а пиши реальный код с реальными алготитмами. f :: a -> ConcreteEffect b. Когда тебе потребуется навернуть абстракции, тогда уже и навернёшь. Не пытайся разработать сферического коня в вакууме. Пиши как пишется и вводи в свою программу абстракции итеративно по мере необходимости.
Аноним 19/01/21 Втр 00:48:57 191469633
>>1880787
>И этого хватает?
Этого не то, что хватает, это будет очень большая проблема, если ты вдруг решишь необоснованно навернуть что-то большее. Вот стартовая точка https://github.com/commercialhaskell/rio

newtype RIO env a = RIO { unRIO :: ReaderT env IO a } - во все поля. Дальнейшее абстрагирование по любому из параметров должно быть обосновано. Иначе ты скатишься в дрочь на абстракции ради абстракций.
Аноним 19/01/21 Втр 01:11:02 191471134
>>1880864
>всё, в чём увлеклись фри монадами
Где ты их нашел в библиотеках?
>Теглесс нигде не видел.
Эмм.. ну https://hackage.haskell.org/package/primitive-0.7.1.0/docs/Data-Primitive-MVar.html#v:newMVar. Tagless в мире Хаскеля это как-бы и есть абстракция по эффекту. Но даже это почти нигде не нужно. Большинство реальных библиотек - это a -> ConcreteEffect b.

Если ты пишешь какую-то свою абстрактную библиотеку, которая использует другие конкретные библиотеки и параметризуется эффектами (например, разные эффекты в зависимости от того, в продакшене ты её запустил или в тестовой среде), то там можно либо tagless final (подменяешь словарь функций), либо free (подменяешь интерпретатор).

По сути, это одно и то же. Ну при подмене словаря функций возможен инлайнинг и оптимизации, как я уже писал, но это не точно, что он сработает.
Аноним 19/01/21 Втр 01:19:59 191471635
>>1881518
Умеренный point-free - это когда можно скипнуть ненужные аргументы без злоупотребления экзотическими комбинаторами. Думаю, ты и сам понимаешь, в чем разница между liftM4 (,,,) и cata f = c where c = f . fmap c . project и твоё личное отношение к point-free не сильно отличается от отношения к point-free других программистов.
Аноним 19/01/21 Втр 01:22:20 191471836
>>1892752
Никак без dependent product. Не усложняй, это не нужно.
Аноним 19/01/21 Втр 01:33:49 191472337
>>1904377
>Линейных типов нет
Да как нет, скачай с девелоперской ветки https://gitlab.haskell.org/ghc/ghc/-/wikis/linear-types

Другое дело, что они практически нахуй не нужны. Был бы от них профит, если бы они реально позволяли бы управлять выделением памяти, как в Rust, и делать язык быстрым. Но пока это чисто конструкция на уровне тайпчекера. И раньше можно было подобное делать на параметризованных монадках.
Аноним 19/01/21 Втр 01:52:37 191473338
>>1914723
>>1904377
А можете нубу пояснить что это за линейные типы? В гугле только на линейную логику наперся, а в пропорсале ghc ничего не понял.
Аноним 19/01/21 Втр 02:40:12 191475239
>>1914733
В гугле про них всё правильно расписано. Это раздел сабструктурной логики https://en.wikipedia.org/wiki/Substructural_type_system, где налагаются дополнительные ограничения в ущерб выразительности, но в пользу вычислимости. На практике это означает то, что в некоторой программе можно статичестки отслеживать выделение и освобождение ресурсов. Т.е. написать программу без мусоросборника. Или автоматически гарантировать корректную работу с ресурсами. Но все сабструктурные логики ущербны и не тьюринг-полны.

Однако есть эмпирическое наблюдение, которое заключается в том, что большую часть реальной программы можно записать в какую-нибудь сабструктурную модель и проверить её автоматичести. И только малая её часть потребует тьюринг-полноты, которую можно проверять отдельно вручную. На этом принципе построены такие языки, как Rust или Agda.

В Хаскель тоже добавили линейные типы (вернее добавляют, пока не основной ветке компилятора вроде). Но там они чисто чтобы было. Т.е. если в Rust они используются во полне практических целях, а именно для управления памятью, в Хаскеле они пока использутся (вернее могут быть использованы, когда добавят), чисто для исследований, на скорость работы обычных программ это никак не повлияет.
Аноним 19/01/21 Втр 11:34:47 191493740
Что почитать по QPL?
Аноним 19/01/21 Втр 13:16:42 191510441
Почему хаскелисты такие слесари?

Вот чем слесарь отличается от инженера. Инженер проектирует, а слесарь выполняет. Инженер должен что-то придумать, а чтобы придумать, надо думать уметь. А слесарь не должен думать, он должен уметь пользоваться инструментом, и ни в коем слечае не думать, а то вдруг придумает что-то другое, а не то, что ему сказали сделать. Слесарь не инженер, он гордится только тем, что умеет пользоваться инструментом.

А теперь посмотрите на толпу хаскелистов и любого энтерпрайзного инженера. Инженер проектирует! У него для этого есть методологии проектирования, парадигмы проектирования, OOD, DDD, даже паттерны у него не чего-попало, а паттерны проектирования, блд! А что хаскелиисты? Зайдите в любой чат и сразу увидите. Хаскель для них все лишь интрумент, они обсуждают сам этот инструмент, никакого проектирования, и им нечем гордиться, кроме своего умения в этот инструмент. Потому что слесари, слесари!
Аноним 19/01/21 Втр 13:19:29 191511142
>>1915104
>слесари?
К слову сказать, именно слесарь был тем человеком, который спас меня и квартиру под нами. Слесарь это моя жена.
Аноним 19/01/21 Втр 13:21:55 191511643
>>1915111
Так об чем же ж и речь. Чтобы поменять унитаз или откачать засарившуюся канализацию - вы вызываете слесаря. Любой хаскелист тоже подойдет. Потому что проектировать унитаз не надо, это неинженерная работа.
Аноним 19/01/21 Втр 13:28:04 191512144
>>1915116
>проектировать унитаз не надо, это неинженерная работа.
Ты уверен? А как же уравнения Навье - Стокса?
Аноним 19/01/21 Втр 13:31:32 191512645
>>1915121
Проектируют унитаз в другом месте совсем другие люди. Инженеры. И для проектирования у них есть инженерные методологии и парадигмы проектирования. А Хаскель это инструмент для слесарей, когда надо уже спроектированный другими унитаз поменять. Слава хаскелистам, слава бравым слесарям!
Аноним 19/01/21 Втр 16:27:45 191528146
>>1915104
Haskell - это изначально дрочь на инструмент. Просто куча слесарей задумались, а каким должен быть самый лучший инструмент? И выдрочили Haskell.

Не вижу в этом ничего плохого. Люди дрочат на Festool, при этом на стройках работают Бошем и Макитой.

Любой профессиональный работник рано или поздно задумывается не только о продукте, но и о об инструменте. Ведь продукт ты производишь и отдаёшь заказчику. А инструмент - это то, что ты каждый день держишь в своих руках.

Поэтому позиция: "Мне похуй на чем программировать, я же профессионал, а язык - всего лишь инструмент" - это позиция не профессионала, а новичка. Как раз профессионалу не похуй, на чем программировать. И язык для него не "всего лишь инструмент", а "тот самый инструмент, который я каждый день держу в руках, который должен быть самым охуенным и удобным, который должен мотивировать меня к творчеству, который должен быть заточен и изящен, глядя на который, я должен понимать, что и любой продукт, созданный с использованием этого прекрасного инструмента, должен быть таким же качественным и продуманным, как сам инструмент".

Я думаю, так можно и быдлокодеров от программистов отличать. Быдлокодер думает: "Ололо, я выучил Джаву на курсах, как бы чего набыдлокодить побыстрее и заработать денег?" А профессиональный программист разбирается в инструментах и уважает людей, обладающих культурой их использования.

"Вот это японская пила, как ей правильно пилить, чтобы получился красивый срез?" - спрашивает один слесарь. "О, я потратил 10 лет, чтобы овладеть японскими пилами, посмотри видео на моём канале, там я объясняю, под каким углом её приложить и куда надавить, чтобы срез получился максимально аккуратным" - гордится другой слесарь. "РЯЯЯ, МНЕ ПОХУЙ НА ИНСТРУМЕНТЫ, Я ПИЛЮ ЗАГОТОВКИ В ЛЕРУА ПО 20 ШТУК В ДЕНЬ НА СТАНКЕ" - кричит инженегр.
Аноним 19/01/21 Втр 18:03:27 191541347
>>1915281
>"РЯЯЯ, МНЕ ПОХУЙ НА ИНСТРУМЕНТЫ, Я ПИЛЮ ЗАГОТОВКИ В ЛЕРУА ПО 20 ШТУК В ДЕНЬ НА СТАНКЕ" - кричит инженегр.

вот замечательно, как подробно описана точка зрения слесаря.
инженер, однако, не "пилит на станке".
он проектирует то, что потом будут пилить слесари (пусть даже 6-го разряда).
проектирует. проектирует. не пилит.
а пока он проектирует, ему не станки нужны, а методология проектирования.
Аноним 21/01/21 Чтв 13:05:47 191703548
>>1915281
Как будто есть хоть какие-то объективные критерии по которым хаскель лучше джавы
Аноним 22/01/21 Птн 20:01:55 191832149
>>1915281
>Просто куча слесарей задумались, а каким должен быть самый лучший инструмент?

Это св. Уодлер то "куча слесарей"?
Нет, вы посмотрите.

Да Уодлер кроме пейперов ничего в жизни не писал, ему слесарить по масти не полагается.
Аноним 23/01/21 Суб 02:08:10 191873050
>>1915413
Ошибаешься. Настоящий инженер - это не чирок-пиздунок, рисующий презентации для начальства, а человек, который понимает процесс производства и управляет им.

Я не утверждаю, что инженер может вырасти только из слесаря (или, переводя на компьютерный язык, архитектор не обязательно должен уметь программировать). Это древняя практика, когда мастер вырастал из рабочего. Хотя и рабочая. Ведь такой мастер понимает, как работает его производстно с самых низов. Но это уже не актуально. Сейчас наверняка можно учить архитектора сразу, и не тратить его время на программирование.

Но инженегр, который который вообще нихуя ни в чем не шарит, это как Рогозин в Роскосмосе. Топить такс у тебя получится, даже методологию затопления такс придумаешь, но ты останешься обычным идиотом и ничего компания под твоим управлением не произведёт. Потому что ты тупо не понимаешь принципов работы своих слесарей, значит не можешь ими адекватно управлять.
Аноним 23/01/21 Суб 02:26:03 191874451
>>1917035
Хаскель хуже Джавы. Как тебе такое? Хуже/лучше - это функционал, отображающий вектор в упорядоченное кольцо. Дальше порядок и правила отображения можешь сам выбирать. Поэтому со совей "объективнстью" иди нахуй. Может быть для тебя объективность - это искуственный хуй в жопе, с чего ты взял, что всем остальным такие критерии по нраву?
Аноним 23/01/21 Суб 09:26:38 191891052
>>1918744
>Хуже/лучше - это функционал, отображающий вектор в упорядоченное кольцо.
Чрезвычайно сомнительное утверждение. Почему в кольцо? Какое ещё кольцо, с какими операциями? Да и вектор из какого пространства?

Априори там только отображение из множества в ЧУМ. Не понимаю, откуда появились дополнительные структуры.
Аноним 23/01/21 Суб 12:05:55 191894953
>>1918730
>Но инженегр, который который вообще нихуя ни в чем не шарит

инженер, который не шарит, это уже не инженер, а менеджер! ))

проблема не в том, что инженер не программирует.
проблема в том, что слесарь не проектирует.
т.е. либо кто-то уже напроектировал за него, либо вместо проекта получится Роскосмос.
Аноним 23/01/21 Суб 12:23:49 191895754
Ананасы, а где найти пояснения по всяким расширеням?, вроде GADTs, DataKinds, PolyKinds, TypeFamilies, etc, но для тупых?
Аноним 23/01/21 Суб 12:44:43 191896755
>>1918957
Бамп вопросу. По основному языку, тайплкасам и основаным на них функторах и монадах тонна статей для тупых, а вот по расширениям, которые много где в хаскеле юзаются, инфу легкую для понимания вебмакакой найти сложно.
Аноним 23/01/21 Суб 13:57:35 191901756
>>1918744
Могла бы для начала погуглить значение слова объективность, рвущаяся макака
Аноним 23/01/21 Суб 20:38:53 191934857
Аноним 23/01/21 Суб 20:42:20 191935058
>>1918730
>Но инженегр, который который вообще нихуя ни в чем не шарит, это как Рогозин в Роскосмосе.

Настоящий инженер проектирует только в UML. Ведь именно для High Kinded Types придумали UML. Да что там, Type Classes, Type Families, - всё это есть только в UML. Отвечай честно и открыто, прямо с ноги: ИН-ЖЕ-НЕ-РИ-Я.
Аноним 24/01/21 Вск 15:33:47 191998059
>>1919348
>для тупых
Мало нам FM
Аноним 24/01/21 Вск 21:42:37 192033060
>>1918957
>>1918967
Проще всего посмотреть в гайды ghc и на их гитлабовскую вики. Для совсем макак не уверена, что существуют гайды по этим темам (зачем?), но вот тут http://dev.stephendiehl.com/hask/ довольно много информации по расширениям разбросаны по разным главам.
Аноним 24/01/21 Вск 21:56:41 192033961
>>1920330
> уверена
трап или цис-тян?
Аноним 29/01/21 Птн 19:47:47 192549262
>>1880225 (OP)
вы тут сидите и по инерции продолжаете хвалить Х-ль, а тем временем ваш Кметт успел перейти на передовой язык Kotlin:
https://github.com/ekmett/cadenza
Аноним 31/01/21 Вск 20:07:53 192729563
>>1925492
>передовой язык Kotlin
>в ридми по ссылке автор жалуется на то, что котлин - говно
Аноним 31/01/21 Вск 20:42:45 192732564
Аноним 12/02/21 Птн 02:47:44 193827265
Аноним 12/02/21 Птн 17:26:50 193874766
Аноним 22/02/21 Пнд 15:31:33 194915567
>>1938747
Даже хаскелистки титьки не показывают.
Куда катится мир?
Аноним 28/02/21 Вск 02:40:29 195356768
Аноним 28/02/21 Вск 02:44:10 195357069
>>1953567
Главное чтобы там монадовошь не завелась
Аноним 28/02/21 Вск 19:26:41 195400470
>>1953567 Срочно нужна комонада!
Аноним 02/03/21 Втр 20:29:17 195573471
>>1954004
Вот и стрелочка повернулась.
Аноним 05/03/21 Птн 04:17:56 195786572
Двач, как писать на хачкеле за еду?
Аноним 05/03/21 Птн 04:18:44 195786773
>>1918957
Прочитай эманюэль, а потом задавай итт вопросы, я тебе расскажу.
Аноним 05/03/21 Птн 04:24:17 195786874
Аноним 05/03/21 Птн 12:15:18 195801375
>>1957868
А если надо не 255 а 1582?
Аноним 05/03/21 Птн 16:37:40 195834776
>>1957867
Какая именно речь Макарона тебя интересует?
Аноним 05/03/21 Птн 17:50:21 195842877
Аноним 05/03/21 Птн 21:42:46 195863678
Аноним 05/03/21 Птн 22:37:20 195866579
>>1958636
Да там политика, в основном.
Дегенеративный контент.
Аноним 06/03/21 Суб 02:17:04 195879680
>>1958013
Тогда smart constructor типа
note :: (KnownNat n, n <= 1582) => Proxy n -> Note
note p = Note $ fromIntegral . natVal $ p

И кастомный Num
Аноним 06/03/21 Суб 12:02:10 195891481
>>1915104
> OOD, DDD, паттерны
Змеиное масло и баззворды, которые отравляют индустрию.
Аноним 06/03/21 Суб 14:34:42 195900282
>>1915281
Но ты ведь не прав, мудила. Язык это действительно всего-лишь инструмент. Все современные языки программирования являются полными по Тюрингу. Какая разница, на каком языке ты будешь вычислять одну и ту же задачу, кроме изъёбистости выполнения оной? На Хаскелле некоторые вещи сделать сложнее, чем на ПХП. Это не делает Хаскелль лучше, это просто complexity bias. Любой алгоритм можно написать на любом ЯПе, ergo любую задачу можно решить на любом ЯПе. Хаскелль это академическая дрочь для изучения возможностей, которые можно привнести в прикладные (прикладные, не Хаскелль, который нихуя не прикладной, что бы ни кукарекали) языки программирования.
Аноним 06/03/21 Суб 16:41:05 195908283
Аноним 07/03/21 Вск 15:52:34 195988084
>>1959002
Из того, что любой алгоритм можно написать не любом ЯП-е не следует, что нет разницы, на каком языке ее писать.
Есть трудозатраты, ограниченность человеческого внимания и т.п..

Пока еще не выросло поколение существ, которые могут писать сложный софт в те же сроки на асме, что и обычные погромисты на подходящих для этого языках.
Идеальный мир, где человек - сверхсущество, которому язык не важен, лишь бы он был Тьюринг-полный - есть только в головах ребят с юношеским максимализмом.
Аноним 07/03/21 Вск 15:53:43 195988185
>>1959880
> Из того, что любой алгоритм можно написать не любом ЯП-е не следует, что нет разницы, на каком языке ее писать.
Из того, что любой алгоритм можно написать нa любом ЯП-е не следует, что нет разницы, на каком языке его описывать.
фикс
Аноним 12/03/21 Птн 15:25:13 196487086
А кто-нибудь знает, есть ли в где-то открытом доступе уже Haskell in Depth?
Аноним 20/03/21 Суб 18:43:02 197245187
>>1959002
>прикладные
В этих прикладных языках нормальные абстракции только в scala можно запилить

Почему 99% прикладных языков говно? Почему на свет появляется такое убожество как Go? Это язык полностью мусорный. Сильно развились шарпы и джавы за последние 5 лет? Добавили какого-то говна на пол шишечки, как всегда. Нет никакого привнесения, есть развивающиеся языки и коммерческое гнильцо.

Если на языке нельзя написать монаду то это хуйня а не язык. (За исключением rust, это годный язык)
Аноним 20/03/21 Суб 18:52:28 197245888
>>1972451
> Сильно развились шарпы и джавы за последние 5 лет?
Эээ блет на шарп не гони.
В него за последние 5-6 лет как раз и добавили, туплы, паттерн матчинг, рекорды, свитч экспрешоны, кое-какие костыли для работы с наллабл типами.
И вроде как в следущих версиях хотят добавить типы-суммы и тайпклассы.

Да и он первый кто принес в популярные языки async/await, и также благодаря linq многие узнали про всякие map/filter.
Аноним 20/03/21 Суб 18:58:10 197246489
>>1972451
> Если на языке нельзя написать монаду то это хуйня а не язык. (За исключением rust, это годный язык)
Алсо, на шарпе можно монаду написать, но не на уровне типов, а в виде "все у чего есть методы Select (fmap) и SelectMany (bind) - монада". Даже аналог ду нотации есть.
Аноним 21/03/21 Вск 01:16:52 197276790
>>1972451
А что такое эти ваши монады?
Аноним 21/03/21 Вск 05:42:23 197283291
>>1972458
>туплы, паттерн матчинг, рекорды, свитч экспрешоны, кое-какие костыли для работы с наллабл типами.
догнали ML 70-го года
>в следущих версиях хотят добавить типы-суммы
а нет, еще не догнали
Аноним 21/03/21 Вск 05:43:33 197283392
>>1972464
traverse :: (Traversable t, Applicative f) => (a -> f b) -> t a -> f (t b) напиши на шарпе
Аноним 21/03/21 Вск 07:53:02 197285893
>>1972458
> и также благодаря linq многие узнали про всякие map/filter.
Откуда же они вылезли?
Аноним 21/03/21 Вск 17:09:13 197327594
>>1972458
>благодаря linq
Все так пиарили, а оказалось, что это функции над итератором. Так пропиарили ленивый связный список, ахуеть просто.
Аноним 22/03/21 Пнд 01:44:38 197375395
>>1972767
Монада - это моноид в категории эндофункторов.
Аноним 22/03/21 Пнд 07:05:22 197387596
>>1973753
Так получилось, что я знаю, что такое эндофунктор и как определяется моноид. Однако я не могу понять, что именно под этими словами понимается в хаскеле, как они толкуются в терминах синтаксиса языка программирования. Статьи с хабра не делают ситуацию понятнее.
22/03/21 Пнд 08:53:16 197392597
Самое смешное, мне никто не мог объяснить монаду. Хотя я человек неглупый и знаю языки.
Всякий раз разводят какую-то хрень типа функция ретурн имеет этот тип, а байнд - вот этот, а вот сахарок ду.
Аноним 22/03/21 Пнд 10:54:46 197396398
>>1973925
Монада - наиболее общий тип данных. Любой другой тип данных (список, дерево, к примеру) можно выразить как монаду.
Аноним 22/03/21 Пнд 13:28:53 197410799
>>1973875
Значит ты не понимаешь общего концепта тайпклассовой системы
Аноним 22/03/21 Пнд 14:53:55 1974190100
>>1974107
Возможно. Однако где найти точные объяснения, что к чему? Легко понять, что набор данных, в котором объекты - типы, а морфизмы - программы, будет категорией. Но как понятия строятся дальше?
Аноним 23/03/21 Втр 00:29:21 1974836101
image.png 52Кб, 200x293
200x293
>>1973875
>что именно под этими словами понимается в хаскеле
вот как эта херня запилена в хаскеле
осторожно длинное, и возможно не полезное

class Functor f where
fmap :: (a -> b) -> f a -> f b

вот это тайпкласс для эндофункторов (в хаскеле называется просто Functor)

fmap должен быть такой, что
[Identity] fmap id == id
[Composition] fmap (f . g) == fmap f . fmap g

это законы, без них функтор не функтор

функтор запиливается для типов вида ⋆ -> ⋆
то есть которые берут тип и отдают тип - [], Maybe, тысячи их

для примера инстанс для Maybe
instance Functor Maybe where
fmap _ Nothing = Nothing
fmap f (Just a) = Just (f a)

fmap применяет f если внутри что-то есть, если нет то нет. простейший функтор

законы работают, как и должны, identity:
>>> fmap id (Just 1)
Just 1
>>> id (Just 1)
Just 1
композиция:
>>> fmap ((+1) . (⋆2)) (Just 1)
Just 3
>>> fmap (+1) . fmap (⋆2) $ (Just 1)
Just 3

между функтором и монадой есть одна шняга, называется апликатив (applicative functor)
это функтор который уже сорт оф моноид, но пока ещё не монада

class Functor f => Applicative f where
pure :: a -> f a
(<⋆>) :: f (a -> b) -> f a -> f b

(в этом классе есть ещё ⋆> и liftA2, о последнем ниже)

каждый апликатив должен быть функтором, иначе он не апликатив

пюре и <⋆> должны быть такие, что
[Identity] pure id <⋆> v = v
[Composition] pure (.) <⋆> u <⋆> v <⋆> w = u <⋆> (v <⋆> w)
[Homomorphism] pure f <⋆> pure x = pure (f x)
[Interchange] u <⋆> pure y = pure ($ y) <⋆> u

я бы сильно в это не вчитывался
но без этих законов апликатив не апликатив

для примера инстанс для Maybe
instance Applicative Maybe where
pure = Just

Just f <⋆> m = fmap f m
Nothing <⋆> _m = Nothing

обратите внимание, что <⋆> выражается через fmap

что нам даёт апликатив:
пюре это возведение a внутрь f (в контекст f)
>>> pure 3 :: Maybe Int
Just 3

<⋆> (название не известно) это вещь в себе
>>> Just (+2) <⋆> Just 1
Just 3

применяется зачастую вот так:
>>> (,,) <$> Just 1 <⋆> Just 2 <⋆> Just 3
Just (1,2,3)

(<$> - это fmap с перевёрнутыми аргументами, в виде инфикс оператора)

немного про liftA2
liftA2 :: (a -> b -> c) -> f a -> f b -> f c
liftA2 f x = (<⋆>) (fmap f x)

он выглядит как fmap, и это не случайно: апликатив сорт оф даёт нам композицию эндофункторов
в данном случае - параллельную. в некоторых библиотеках так выражается паралеллизм, например
(,) <$> Future a <⋆> Future b возможно ждёт пока доедут какие-то вычисления или байтики по сети и возвращает нам (a, b)
(это не конкретный пример, а псевдокод)
есть ещё liftA3, liftA4 и выглядят они соответствующе

class Applicative m => Monad m where
(>>=) :: forall a b. m a -> (a -> m b) -> m b

в монаде есть ещё >> это частный случай >>=, и return - то же что и pure, но по историческим причинам эта функция есть в обоих тайпклассах.
(>>=) в хаскеле называется bind, в некоторых других языках можно увидеть join или flatMap (не имеет отношения к fmap, ну почти)

законы
[Left identity] return a >>= f = f a
[Right identity] m >>= return = m
[Associativity] m >>= (\x -> f x >>= g) = (m >>= f) >>= g

инстанс для Maybe
instance Monad Maybe where
(Just x) >>= k = k x
Nothing >>= _ = Nothing

и примеры законов
Left identity:
>>> return 1 >>= \x -> Just (x+1)
Just 2
>>> (\x -> Just (x+1)) 1
Just 2

Right identity:
>>> Just 1 >>= return
Just 1

ассоциативность не буду приводить, предлагаю поверить на слово

что нам даёт монада - это упорядоченную композицию функторов
допустим у нас есть функция (a -> Maybe b), например она парсит что-то и при успехе возвращает Just b, при неудаче Nothing
мы можем взять и скомпозировать кучу таких функций, но уже упорядочено. в отличии от апликатива, где композиция была другого рода:
a -> Maybe b >>= (b -> Maybe c) >>= (c -> Maybe d) и так далее
вот это - тот самый моноид в категории эндофункторов:
>>= это бинарная операция,
return (или pure) это нулевой элемент,
категория эндофункторов - это множество функций в контексте m (возвращающих значение в контексте m)

такие дела
Аноним 23/03/21 Втр 00:46:13 1974846102
Аноним 24/03/21 Срд 09:43:26 1975872103
>>1974836
Борщи, но хорошо расписал.
Аноним 24/03/21 Срд 09:54:31 1975880104
С
Аноним 24/03/21 Срд 10:18:23 1975895105
>>1972832
>догнали ML 70-го года
О, наш человек.
Аноним 27/03/21 Суб 03:55:38 1978676106
Недавно узнал о такой приблуде как XMonad и упитанно прихуел. А потом ещё больше прихуел от того, что она существует с 2008 года. И это же ведь не какой-то там хелло ворлд или парсер жсона, не окошко с зигой и не пищалка ебливая, а целый ебаный полнофункциональный расширяемый оконный менеджер в 500 ебаных строк кода судя по вики. То, что казалось бы только на СИ по хардкору и пердолить реализовано в 500 строчек на высокоуровневом декларативном тайп-сейф языке с производительностью не хуже СИшного аналога dwm. Что-то это меня вдохновило, дало веру в хаскель, что ли. На днях обязательно буду наворачивать.
А ещё говорят что на хаскеле нет реального софта в реальном мире. Собстна, за этим я и зашёл. Какие ещё есть на просторах интернетов легитимные энд-юзер проги на хаскеле? Не пруф оф концепт, а именно реальный софт который используют не вымышленые люди, как XMonad и XMobar.
Аноним 27/03/21 Суб 09:28:53 1978717107
Не совсем понимаю в чем разница между сум-типами и ADT.
ADT это обобщение сум-типов?
Аноним 27/03/21 Суб 11:45:26 1978850108
>>1978676
можешь связаться с компанией MetaLamp (раньше FSD), они пишут на хаскеле, у них еще обучающая программа (роадмап можно сказать) есть по нему
примеры кажецо есть прям на их сайте, но не помню точно
Аноним 27/03/21 Суб 11:45:59 1978851109
>>1978676
есть какая-то контора, которая регулярно вербует вкатышей, они зачем-то бэк пишут на хаскеле
Аноним 27/03/21 Суб 11:47:32 1978853110
>>1978676
> что казалось бы только на СИ по хардкору и пердолить реализовано в 500 строчек на высокоуровневом декларативном тайп-сейф языке с производительностью не хуже СИшного аналога dwm.
Та ладно, qtile имеет тот же функционал, но написан на питоне.
> Какие ещё есть на просторах интернетов легитимные энд-юзер проги на хаскеле?
Мало, но они есть. Блокчейн кардано, парсер всего пандок, сервер для постгре postgrest, анализатор баш скриптов shellcheck. Это из тех, которые популярны, опенсорсны и которые юзают не только хаскелисты. Ну а так еще есть termonad, альтернатива гиту и куча софта для разработки на самом хаскеле. сущестует три lsp сервера, каждый дебил создает свой форматировщик и тд
Ну и вот статти по закрытому прод софту на хаскеле: https://serokell.io/blog/top-software-written-in-haskell
Аноним 27/03/21 Суб 11:56:18 1978856111
>>1978676
> То, что казалось бы только на СИ по хардкору и пердолить
На чем ВМы только не пишут. И на луа есть.

> с производительностью не хуже СИшного аналога dwm
Сам хмонадом пользуюсь, двм, наверное, всё же лучше. Пользовался бы им, если бы конфигурировать было его удобно. В хмонаде просто импортишь и настраиваешь, а в двм патчить надо.
Но и хмонада есть свои проблемы. Хмобар для простенького бара жрёт нормально так оперативки. Если запускаешь игры в полноэкранном режиме, то они нахуй пропадут, если они так запускаются по дефолту, то изволь переходить в другую сессию с другим вм, чтобы в настройках изменить на окно это если нет текстовых файлов настроек нормальных. У меня ещё и табсмод кривовато работает.
Впрочем, пользоваться можно, но не супер, так скажем.
Аноним 27/03/21 Суб 12:11:02 1978865112
>>1972832
я не говорю что шарпы самый охуенный язык для чистого фп. Но он в этом плане гораздо лучше джавы, плюсов, питонов и тд.
И ты спросил что в него добавили за последние 5 лет. Вроде как дохуя фич.
>>1972858
>>1973275
Ну блять, эта хуета в 2005-2008 появилась. А статейки, где показывали какой хачкиль крутой только потому что в нем есть map и filter, были даже в начале 10х.
>>1972833
Ура, в хаскиле есть аналоги итераторов по будь чему. Очень рад за него.
Аноним 27/03/21 Суб 12:13:21 1978867113
>>1978856
>Хмобар для простенького бара жрёт нормально так оперативки
Есть dzen2
>Если запускаешь игры в полноэкранном режиме, то они нахуй пропадут
Хуй знает про что ты. Но мой калькулятор тянет только майнкрафт и факторио, и они нормально запускались.
Аноним 27/03/21 Суб 12:20:35 1978872114
>>1978867
> Хуй знает про что ты. Но мой калькулятор тянет только майнкрафт и факторио, и они нормально запускались.
Не у всех игор такое, но у многих. У меня из последнего что ставил вроде точно не помню встречалось такое с Iratus и Blasphemous.
Аноним 27/03/21 Суб 13:57:24 1978931115
>>1972464
Идиоматические монады можно писать на чём угодно
>>1978865
>я не говорю что шарпы самый охуенный язык для чистого фп. Но он в этом плане гораздо лучше джавы, плюсов, питонов и тд.
И ты спросил что в него добавили за последние 5 лет. Вроде как дохуя фич.
Каких фич? Даже Фсярп выглядит кастрированно даже на фоне скалы. И нахуй ты это говно сюда тащишь?
>Ура, в хаскиле есть аналоги итераторов по будь чему. Очень рад за него.
Траверс - не итератор
Итератор в рамках хаскеля реализован быть не может, поскольку каждый тайп конструктор в первую очередь является данными с выполнением задач "контейнероности" только на стороне вооброжения программиста
Аноним 27/03/21 Суб 21:08:24 1979156116
Аноним 05/04/21 Пнд 21:07:41 1987169117
>>1978717
ADT включают в себя типы-суммы и типы-произведения.
Аноним 07/04/21 Срд 13:43:05 1988867118
Аноним 10/04/21 Суб 11:19:33 1991697119
>>1978931
Аналог традиционных итераторов из ОО в хаскеле есть и это ленивые связные списки же.

Из разбор - это всё равно что while(iter.next()) { head = iter.getCurrent(); ... }
Аноним 11/04/21 Вск 00:42:46 1992433120
>>1991697
Просто у тебя припукнутые критерии аналогичности
Аноним 11/04/21 Вск 02:51:34 1992475121
>>1992433
Так это буквально итератор выходит, всё что можно сделать на итераторах в ОО языке можно сделать используя в качестве итератора ленивые списки.

Не зря же практически у каждой коллекции в хаскеле есть toList, даже у тех, что Foldable не реализуют
Аноним 11/04/21 Вск 17:43:15 1992819122
photo2020-09-15[...].jpg 28Кб, 500x654
500x654
Привет, господа хаскеллисты. Есть вопрос скорее о ФП в целом, чем о конкретном языке, в хаскелле у меня такой же вопрос бы встал, но речь пойдет о JS.

Вот это неприятная сторона ФП - мало кто сможет ответить и помочь, нужно много литературы прочесть и много практики. С одной стороны плюс, с другой немножко обидно. Но все же картина понемногу складывается и я понемногу вкатываюсь в алгебраические структуры т.к. уже уверенно чувствую себя в композиции функций и банальном ФП в целом.

Значит, использую Ramda вместе с Redux внедрил на работе, не борщехлеб, пропагандирую ФП среди коллег. Уже задал этот вопрос в рамда тредике англоязычном. В частности, ФП подход удобный из-за того что можно композить селекторы из Редакса (функции с сигнатурой selectorFn :: State -> a ).

Допустим, у нас есть 2 селектора, один из них берет из стейта число, второй массив. И я хочу взять элемент из массива используя этот номер как индекс. В Рамде это может выглядеть так:

>// nthOfList :: [string] -> State -> string
const nthOfList = list => R.pipe(
R.path(["myData", "myIndex"]),
R.nth,
list
);

>// list :: State -> string[]
const list = R.pipe(
R.path(["myOtherData", "myArray"])
);

Теперь чтобы взять элемент по индексу я передаю стейт в эти функции и применяю результат list к nthOfList

// >f(g(x), x)
const elementByIndex = nthOfList(list(state))(state);

Очевидно, это становится тяжело читать. И я узнаю что здесь можно применить chain:

const elementByIndex = R.chain(nthOfList, list);
elementByIndex(state);

Теперь, вопрос: это ведь какой-то паттерн в ФП, правда? Могли бы ли вы анончики подсказать что это значит, что эти два селектора можно выразить через chain, ведь сhain это одна из функций Monad тайп класса, так ведь? Вопрос скорее более абстрактный, чем конкретный - возможно вы еще сможете направить меня на какую-то книжку или подсказать что Редакс это на самом деле Update монада. Я чувствую что с этими селекторами есть некоторое объединяющее их свойство - а именно State как финальный первый параметр всегда - и что я могу упростить композицию селекторов завернув их во что-то, что всегда будет вызывать их передавая в них стейт как только я скажу "run" финальному селектору. Если это имеет смысл то что я сказал.
Аноним 11/04/21 Вск 18:18:39 1992843123
>>1992819
Это значит что функции с фиксированным типом входного аргумента является монадой и соответственно такие функции можно комбинировать через функцию (>>=)
Аноним 11/04/21 Вск 19:35:52 1992892124
>>1992475
До сих пор не понимаю, зачем ты пытаешься на хаскель натянуть именно слово "итератор"
>Не зря же практически у каждой коллекции в хаскеле есть toList, даже у тех, что Foldable не реализуют
Каждая коллекция и является траверсабельной, а не итерабельной
Аноним 11/04/21 Вск 19:49:31 1992900125
>>1992892
Далеко не все коллекции реализуют что Foldable, что Traversable. Простейщий пример - IntSet и ему подобные.
Аноним 11/04/21 Вск 20:38:21 1992930126
>>1992900
Переворот слов с перекрутом значений зашкалил
Я надеюсь, что это просто жирный троллинг
Аноним 11/04/21 Вск 20:43:19 1992934127
>>1992930
Тут дело в том, что между ОО итератором и хаскелевским списком можно буквально изоморфизм построить.

Т.е. вот пример, тут мы в качестве ОО итератора возьмем тайпкласс имеющий условно интерфейс как у ОО итератора + экзистенциальный тип и получим Iter a, который полный аналог интерфейса итератора из любого ОО языка.

Ну и сам изоморфизм и всё такое:

class Iterator this a where
next :: this -> Maybe (a, this)

data Iter a = forall this. (Iterator this a) => Iter this

instance Iterator [a] a where
next [] = Nothing
next (x:xs) = Just (x, xs)

iteratorIso :: Iso' (Iter a) [a]
iteratorIso = iso toList fromList where

fromList :: [a] -> Iter a
fromList = Iter

toList :: Iter a -> [a]
toList (Iter initial) = unfoldr next initial

И условный пример подобных итераторов, чтобы можно было убедиться, что изоморфизм действительно работает ожидаемым образом:

data RangeState = RangeState { start :: Int, until :: Int }

instance Iterator RangeState Int where
next RangeState { start, until } | start == until = Nothing
| otherwise = Just (start, RangeState { start = start + 1, until })

newtype InfiniteState = InfiniteState { start :: Int }

instance Iterator InfiniteState Int where
next InfiniteState { start } = Just (start, InfiniteState { start = start + 1 })
Аноним 11/04/21 Вск 23:00:45 1993132128
>>1992819
Я сварщик ненастоящий, но тебя возможно заинтересуют линзы
12/04/21 Пнд 04:22:45 1993347129
>>1993132
Линзы хороши, но там у меня функции не только проперти читают.

В рамда чятике ответили - у меня случай Reader монадки. Алсо, палю годноту: https://gist.github.com/Avaq/1f0636ec5c8d6aed2e45
Аноним 12/04/21 Пнд 04:23:04 1993348130
Аноним 12/04/21 Пнд 05:26:24 1993363131
>>1992934
>между ОО итератором и хаскелевским списком
Между нехаскелевским нельзя?
>условно интерфейс
>экзистенциальный тип
И получаем "условный "интерфейс" итератора, который в рамках самого хаскеля - траверс обычной структуры

Итератор подразумевает "контейнеринг" каких-то "данных", на абстрактном уровне чистого ФП с иммутабельными копиями это не имеет никакого смысла
Аноним 12/04/21 Пнд 08:43:22 1993427132
>>1993347
А линзы и не только для чтения пропертей.
Аноним 12/04/21 Пнд 10:12:53 1993467133
>>1993363
Ну подобный итератор с экзистенциалом делает ровно то же, что и его ОО собрат, пряча точный тип обходимого контейнера внутри себя.
Аноним 12/04/21 Пнд 10:17:30 1993472134
Аноним 12/04/21 Пнд 10:57:14 1993512135
>>1993363
>Между нехаскелевским нельзя?

Тут нужен именно иммутабельный ленивый список, это важная деталь.

А так-то в других языках тоже можно подобный трюк провернуть, если есть желание:
https://scastie.scala-lang.org/D5U6II7hQxOySByOo4352A
Аноним 13/04/21 Втр 01:49:58 1994297136
Аноним 13/04/21 Втр 08:33:18 1994351137
Кто-то может пояснить зачем нужны фреймовые обструкты, когда есть кольцевые конвейерные маппинги?
Аноним 18/04/21 Вск 13:41:29 2000181138
>>1964870
У меня есть - могу куда-нибудь залить.
18/04/21 Вск 15:39:39 2000323139
>>1994351
Не нужны, это хуйня без задач, как и всё остальное в этом треде.
Аноним 18/04/21 Вск 18:09:32 2000532140
Какого хера!
> Несколько месяцев заходил в этот тред и видел, что новых сообщений нет
> https://2ch.hk/pr/arch/2021-04-17/res/1488256.html
> "хаскель тред совсем мёртвый стал"
> всё это время существовал другой тред
Аноним 18/04/21 Вск 18:54:43 2000597141
>>2000323
>мам для моих крудов ФП нинужно и я ниасилил, скажи им что ни нужно!!1
Аноним 18/04/21 Вск 20:04:09 2000690142
>маам мой хацкиль всем очинь нужён
А что ты скажешь о том простом факте что твой фп-код под капотом превращается в код на императивном C да и рекурсия твоя оптимизируется в цикл?
Аноним 18/04/21 Вск 20:49:41 2000707143
>>2000690
То что ФП это для людей, а не для машины.
Аноним 18/04/21 Вск 20:56:21 2000719144
>>2000707
Это машины так тебя заставляют думать.
19/04/21 Пнд 12:28:32 2001192145
>>1880225 (OP)
господа, што такое фри монады и таглес файнал? есть годные источники по изучению этой нечести?
Аноним 19/04/21 Пнд 14:12:46 2001325146
>>2001192
"The book of monads" by Alejandro Serrano Mena.
Аноним 19/04/21 Пнд 14:29:16 2001350147
>>2001325
я наверно в шары долбился, но не видел этих тем. пойду гляну еще раз.
Аноним 19/04/21 Пнд 14:47:09 2001361148
>>2001192
Файнал монады похожи на привычную из ООП историю об интерфейсе и имплементации:
- создаёшь тайпкласс, который описывает какой-то интерфейс
- создаёшь свою кастомную монаду
- привязываешь их друг к другу, объявив инстанс тайпкласса для монады, т.е. объявляешь свою кастомную монаду имплементацией интерфейса-тайпкласса
- разные функции ожидают интерфейс, а ты им подкидываешь имплементацию.

Фри монады тот же интерфейс объявляют не в виде тайпкласса, а в виде GADT. А имплементация интерфейса превращается в интерпретацию операций - объявляешь какую-то функцию-интерпретатор из фри монады в кастомную монаду. Ты как будто внутри языка создаёшь ещё один интерпретируемый язык и интерпретатор для него.
Аноним 19/04/21 Пнд 15:08:34 2001388149
>>2001361
Ты потерял важную деталь - таглесс файнал позволяет далеко не только монады описывать, а фри монады - это именно про интерпретирование монады с кастомными действиями в целевую монаду
Аноним 19/04/21 Пнд 15:14:44 2001402150
>>2001361
Спасибо. Очень интересно, буду разбираться дальше.
Аноним 19/04/21 Пнд 15:44:35 2001459151
>>2001388
Ещё нужно добавить, что в файнал подходе функции перечисляют как минимум два тайпкласса: один, который ты создал как интерфейс создаваемой тобой монады, а второй - это собственно тайпкласс Monad.

Хотя наверное иногда можно обойтись без объявления об ожидании тайпкласса Monad.
Аноним 19/04/21 Пнд 17:18:18 2001631152
>>2001459
Конечно, можно, и более того, лучше не указывать Monad, если можно обойтись более слабыми конструкциями, типа функтуров, аппликативов, селективов и стрелок.

По сути в final tagless подходе, ты с помощью своего тайпкласса указываешь необходимые в данной доменной области операции, а с помощью второго тайпкласса типа Monad, Applicative и т.п. указываешь, как эти операции можно скомбинировать в программу.

И сила как раз final tagless, в том, что эти две вещи: доменные операции и способ их комбинирования - полностью независимы друг от друга.
Аноним 20/04/21 Втр 08:12:20 2002006153
image.png 132Кб, 1180x431
1180x431
>>2001631
Но и о недостатках нужно помнить.
Александр Гранин хорошо в своих докладах описывал недостатки FT.
Среди них как раз всплывание всего списка низкоуровневых эффектов (деталей реализации) в констрейнтах домена и сложности разграничения эффектов в разных слоях логики.
https://youtu.be/u1GGqDQyGfc
Аноним 20/04/21 Втр 10:23:16 2002102154
>>2002006
Ох, не надо слушать Гранина неиронично, он сам TF плохо понимает.

Если у тебя в TF каким-то образом в эффектах вверх всплывает MonadUnliftIO (или Sync в случае скаловских котов) - значит ты свою доменную модель спроектировал неправильно.

Потому что в доменном коде при TF у тебя не должно быть подобных эффектов, они слишком мощные для доменного кода.
Аноним 20/04/21 Втр 10:26:50 2002107155
>>2002006
Ну и фри монады, опять-таки норм использовать как Гранин их подразумевает, только в крупных фреймворках и около всякого IO, где их нулевая производительность и дикий GC pressure никому не помешают.

А TF в грамотно написанном по перформансу коде (а это в случае хаскеля значит - инлайним и специализируем ВСЁ что видим) - имеет практически нулевую цену.
Аноним 20/04/21 Втр 11:30:57 2002164156
>>2002102
Это всё, конечно, хорошо, но где же можно воочию лицезреть тот самый "правильный" TF, в таком случае?

Ну и сам факт того, что на TF так легко писать "неправильно", уже о чем-то говорит, ведь в больших проектах если где-то можно писать неправильно, то оно БУДЕТ написано неправильно.

(Но видео-то глянь, там не только UnliftIO всплыло)
Аноним 20/04/21 Втр 12:03:42 2002186157
>>2002164

Я на этом докладе лично был и реакция аудитории там всё говорила.

На TF сложно писать неправильно как раз по той причине, что любую такую утечку неограниченных эффектов будет явно видно в сигнатуре.

А с вариантом с фри монадами, у тебя будет какой-нибудь runAnyEffect :: IO a -> MyFreeMonad a и всё, ты никогда не узнаешь, что он где-то там внутри используется.
Аноним 20/04/21 Втр 12:18:19 2002197158
>>2002186
> runAnyEffect
Но такую штуку же будет сразу видно. Так себе в ногу и в FT можно выстрелить.

И всё же, есть какие-нибудь исходники, которые можно почитать на пример расово верного TF?
В статейках всё красиво обычно, но это либо очень просто, либо вырвано из контекста. Хотелось бы посмотреть на TF "в естественной среде обитания", так сказать.
Аноним 20/04/21 Втр 12:23:28 2002204159
>>2002197
> Но такую штуку же будет сразу видно.

Такую штуку будет видно, только если напрямую лезть в исходники и смотреть, а что же там написано и какие эффекты фри монады юзаются.

А вот использование всяких UnliftIO видно сразу в сигнатуре функций их использующих.
Аноним 20/04/21 Втр 13:49:21 2002342160
>>2002204
Я имею в виду, что присутствие такой вот в сорцах вообще
> runAnyEffect
должно приводить к хорошему подзатыльнику автора сей поделки.

И очевидно, что сделать такой вот runAnyEffect можно в общем лишь имея в скоупе конструкторы дата структуры, на которой построена фри монада. Так что если это не говнокод, где фри монада заимплементирована в том же модуле, где лежит ее интерпретатор и код, ее использующий, или где всё экспортируется везде, то такого рода сомнительные функции будут хорошо заметны, находясь в модуле с определением фри монады, или с ее интерпретатором.

Короче, если не мудачить прям совсем безбожно (нарушая все возможные принципы проектирования ПО), то сложно представить, как можно такую проблему получить.
Аноним 20/04/21 Втр 14:08:24 2002364161
>>2002342

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

И проблема как раз в том, что ты не посмотрев исходники данной функции - не поймешь, используется ли она такие черные ходы в IO или нет.
Аноним 21/04/21 Срд 15:33:45 2003488162
>>2002364
Приведи пример из фри монад Гранина, ссылку.
Аноним 21/04/21 Срд 15:37:03 2003492163
Как в хаскелле реализована IO монада? Можно посмотреть соурскод?
Аноним 21/04/21 Срд 15:50:26 2003501164
>>2003492
Как и любая другая монада
Интерфейс для случаев выхода в реал ворлд находится на уровне интерпритации компелятором
Аноним 21/04/21 Срд 15:52:53 2003508165
>>2003501
Т.е не весь язык можно описать в терминах самого языка? Какой-то ограниченный язык.
А как тогда делать кастомную монаду с эффектами?
Аноним 21/04/21 Срд 16:11:44 2003530166
>>2003508
Ты не понимаешь ни что такое монада, ни что такое эффект, но хочешь монаду с эффектом. лол
Аноним 21/04/21 Срд 16:15:08 2003533167
>>2003530
Ок переформулируем.
Как компилятор понимает какую монаду интерпретировать, а какую не интерпретировать?
Аноним 21/04/21 Срд 16:17:41 2003537168
Аноним 21/04/21 Срд 16:32:01 2003560169
>>2003533
Короче, краткий курс по монадам и IO в хаскеле.

Есть у нас красивый ленивый язык (где аргументы переданные в функцию вычисляются только при их использовании).

Как сделать в нём ввод и вывод так, чтобы пользователю языка не оторвало руки от ленивости и компилятор знал какие обращения к вводу и выводу должны когда идти и когда их порядок нельзя менять?

Ответ простой - надо чтобы все подобные эффекты принимали и возвращали какой-то токен, который компилятор не может создать из ничего и таким образом установить для компилятора жесткий порядок между побочными эффектами.

Собственно тогда каждая функция с побочным эффектом будет выглядить как Token -> (ReturnType, Token), но руками такие функции соединять друг с другом не очень удобно, т.к. будет бойлерплейт в духе:

(value, token1) = myEffect1 token0
(value2, token2) = myEffect2 token1
(value3, token3) = myEffect3 token2

Но можно написать такую функцию, которая будет этот токен за нас пробрасывать:
type MyIO a = Token -> (a, Token)
bind :: MyIO a -> (a -> MyIO b) -> MyIO b

И вот мы и приходим к тому, что наше IO будет монадой (т.к. map, pure, <$> для него легко по аналогии написать).

И если залезть в base хаскеля то там именно оно и будет и любое IO можно разобрать в подобную функцию с State# RealWorld -> (# State# RealWorld, a #):
https://hackage.haskell.org/package/base-4.15.0.0/docs/src/GHC-Base.html#unIO


Аноним 21/04/21 Срд 16:34:50 2003564170
>>2002364
>>2003537
> И проблема как раз в том, что ты не посмотрев исходники данной функции - не поймешь, используется ли она такие черные ходы в IO или нет.
Можно задокументировать это, создав инстанс MonadIO.

>>2002186
Что-то не понял пример про runAnyEffect :: IO a -> MyFreeMonad a.
Делать свою монаду инстансом MonadIO - это плохо?
Аноним 21/04/21 Срд 16:37:44 2003568171
>>2003508
> Т.е не весь язык можно описать в терминах самого языка? Какой-то ограниченный язык.
То же самое можно сказать о математике и логике.

А вообще вопрос интересный, можно ли создать монаду более фундаментальную и низкоуровневую что IO.
Аноним 21/04/21 Срд 16:39:08 2003573172
Аноним 21/04/21 Срд 16:55:05 2003588173
>>2003564
Можно задокументировать это, создав инстанс MonadIO, но так тогда тебе всё равно придется писать в final tagless стиле, чтобы MonadIO в констрейнтах функций было видно, где эти черные ходы юзаются.

> Делать свою монаду инстансом MonadIO - это плохо?

Ты делаешь свой доменный эффект для бизнес логики, а потом в центре него оставляешь дыру через которую можно любой произвольный эффект сделать?

Спрашивается - почему бы сразу и не писать в конкретном эффекте, если ты всё равно оставяешь такую штуку?
Аноним 21/04/21 Срд 16:58:03 2003594174
>>2003568
> То же самое можно сказать о математике и логике.
Имеется в виду, что в языке есть те функции, которые определить невозможно. В C к примеру все функции определены, так как сишка это ассемблер на спидах. В JS тоже множество функций, у которых просто НЕТ определения. Операция плюс, или console.log, к примеру. И это бесит.
Аноним 21/04/21 Срд 17:07:06 2003602175
>>2003594
В си дофига зато аттрибутов и макросов, которые невозможно выразить в языке, потому что они управляют именно поведением компилятора.

И опять-таки примитивные типы, которые ты никак на самом языке не опишешь и т.п.
Аноним 21/04/21 Срд 17:09:35 2003605176
>>2003602
Мы говорим сейчас про функции, а не про работу термов языка.
Аноним 21/04/21 Срд 17:22:15 2003612177
>>2003560
>(value, token1) = myEffect1 token0
(>value2, token2) = myEffect2 token1
>(value3, token3) = myEffect3 token2

Вот это вот очень сильно похоже на аффинные типы в клин/меркари, только там токен обозначает измененный мир.

main(IO0, IO) :-
io.write_string("fib(10) = ", IO0, IO1),
io.write_int(fib(10), IO1, IO2),
io.nl(IO2, IO).

https://en.wikipedia.org/wiki/Mercury_(programming_language)#Examples

Mode declarations can also specify so-called “unique modes”. Mercury’s unique modes are similar to “linear types” in some functional programming languages such as Clean. They allow you to specify when there is only one reference to a particular value, and when there will be no more references to that value. If the compiler knows there will be no more references to a value, it can perform “compile-time garbage collection” by automatically inserting code to deallocate the storage associated with that value. Even more importantly, the compiler can also simply reuse the storage immediately, for example by destructively updating one element of an array rather than making a new copy of the entire array in order to change one element. Unique modes are also the mechanism Mercury uses to provide declarative I/O.

https://www.mercurylang.org/information/doc-latest/mercury_ref/Unique-modes.html

Но очевидно что монады и аффинные типы это разный подход, даже концептуально, так что что-то тут не чисто.
Аноним 21/04/21 Срд 17:24:36 2003617178
>>2003594
На каком-то этапе ты переходишь от Си к Ассемблеру.
Опиши цикл for в терминах самого цикла for, не переходя в Ассемблер? Си какой-то ограниченный.
А если можно переходить из одного языка в другой, то точно так же переходим от Хаскеля на тот язык, на котором написан компилятор Хаскеля.
Аноним 21/04/21 Срд 17:26:40 2003623179
>>2003605

Ну тут деталь, что ядро языка в хаскеле очень маленькое (считай тупо лямбда исчисление) и чтобы его не усложнять, всякие магические вещи, которые в других языках являются его конструкциями (например та же работа с указателями) в хаскеле сделана через такие магические функции, которые при кодгене компилятор уже раскрывает в нужные операции.
Аноним 21/04/21 Срд 17:32:02 2003630180
>>2003617
Я могу описать функцию print условно как:
print x -> какой-то байткод
Т.е смог определить функцию. У хаскелла же какая-то черная магия, которая "просто работает".
Аноним 21/04/21 Срд 17:34:03 2003633181
>>2003612
Это по сути тот же приём, только без явного использования афинных типов и со спрятыванием пробрасывания токена под капот IO.

Ну и с возможностью слома всей этой системы, если особо нужно, т.к. токен не афинный и не линейный и если ты хочешь найти себе приключений на свою задницу, то ты можешь его явным копированием сделать кучу хитрых трюков.

И заодно сделать эффективное ленивое IO при этом, т.к. некоторые ленивые операции с вводом выводом в хаскеле сделаны именно так через дублирование токена: см http://hackage.haskell.org/package/base-4.14.1.0/docs/src/GHC.IO.Unsafe.html#unsafeDupableInterleaveIO и ему подобные функции, через которые ленивыйввод вывод можно выразить.
Аноним 21/04/21 Срд 17:54:23 2003648182
>>2003630
Ну если байткод считать валидной конструкцией языка, то как бы да, полноценный язык. Но понятно же, что это не язык полноценный, а смесь двух языков, просто язык позволяет встраивать в свои исходники инструкции на другом языке (если я правильно понял пример с print).
Теоретически можно было бы все языки сделать полноценными, позволив встраивать в их исходники байткод. Но ты же не будешь серьёзно этого требовать.>>2003630
Аноним 21/04/21 Срд 17:58:08 2003654183
>>2003648
Ну в хаскеле по сути несколько внутренних представлений сравнимых с байткодом и при особом желании их все можно компилятору скормить при желании.

Т.е. есть Core, STG и CMM и на них вполне себе можно попробовать отдельно написать код и слинковаться, вроде бы кто-то так даже делал. И где-то весит пропозал на то, чтобы функции в этих представлениях можно было явно инлайнить в исходники.
Аноним 21/04/21 Срд 18:30:41 2003691184
>>2003654
А как в erlang сделали так, чтобы можно было на ходу заменять части программы? Почему именно erlang? Может и в хаскеле такое появится?
Аноним 21/04/21 Срд 18:37:03 2003697185
image.jpeg 11Кб, 227x222
227x222
>>2003691
Ты уже давно протёк
Аноним 21/04/21 Срд 18:37:51 2003699186
>>2003691
Потому что у эрланга байткод именно выполняется в рантайме, а в хаскеле - все эти представления существуют только на этапе компиляции, т.к. хаскель в итоге в машинный код компилится.
Аноним 21/04/21 Срд 19:02:54 2003728187
>>2003588
> Ты делаешь свой доменный эффект для бизнес логики, а потом в центре него оставляешь дыру через которую можно любой произвольный эффект сделать?
> Спрашивается - почему бы сразу и не писать в конкретном эффекте, если ты всё равно оставяешь такую штуку?
Потому что в доменном эффекте удобнее описать действия?

Ну, типа, как делают в ORM-ах, которые object relational mapping. Там обычно есть какое-то API или DSL для создания запросов, и где-то с краю есть возможность запустить запрос, описанный в виде обычного SQL в строке.

Ну хорошо, если поставить перед собой цель убрать эту дыру, то как это делается?
Вот тебе нужно, чтобы вместе с твоими доменными операциями можно было выполнять IO-операции.
Аноним 21/04/21 Срд 19:27:07 2003757188
>>2003728
Такой пример: есть какая-то монада с состоянием (State или StateT), которую я объявил как MonadIO.
Пользователь может вызвать любое IO-действие вместе с действиями моей монады, но эти действия не меняют состояние, хранящееся в монаде. Что в этом плохого?

Меня больше интересует вопрос, как в одном блоке работать с двумя разными состояниями. Объединять две монады в один стек монад? Какой есть способ, минимизирующий церемонии и свистопляски с типами?
Аноним 21/04/21 Срд 19:28:39 2003759189
>>2003691
Потому что в эрланг это всего лишь

loop(Func, State) ->
__receive
____{apply, Data, Pid} ->
______{Result, NewState} = Func(Data, State)
______Pid ! Result
______loop(Func, NewState)
____{code_change, NewFunc} ->
______loop(NewFunc, State)
__end.

Ну и там сразу рантайм на это заточен, загрузка нового кода, хранение старой и новой версии кода, переключение. Но даже там для stateful частей чаще всего очкуют его юзать, так как нужно много чего предусмотреть, нужно или новый код писать с расчетом на то, чтоб он не распидорасил старый стейт, либо, что еще сложнее, мигрировать стейт, что подразумевает фриз старого кода на время миграции, что уже не совсем риал-тайм, ну то есть оно все еще неплохо что можно зафризить отдельные части и действовать по-этапно, но это пиздец какие тонкие инженерные изьебы и на большинстве задач людям просто проще переключить один контейнер на другой в кубере.
Аноним 21/04/21 Срд 19:39:02 2003771190
>>2003759
Наверное есть какие-то паттерны специально для таких случаев.
Что-то вроде CRDT, который будет постепенно переезжать из старой версии в новую, а когда переезд закончен, старая версия благополучно отклучается и остаётся только новая.
Аноним 21/04/21 Срд 20:44:44 2003804191
>>2003757
Если мы говорим про final tagless, то если мы хотим, чтобы у нас констрейнты на функции говорили нам о том, какие эффекты мы можем применить:

confirmOrders :: (HasAccountDb m, HasBookKeepingService m, HasAccountCache m, MonadPlus m) => [Order] -> m [ConfirmedOrder]

И таким образом мы знаем, что в этой функции никаких черных ходов не используется и всё что она может сделать - это вызвать одну из функций из выше перечисленных тайпклассов.

И если на этой функции будет констрейнт MonadIO, то мы теряем вот эту возможность знать, что внутри за хрень будет происходить. Потому что это значит, что там внутри будет всё что угодно.


> Объединять две монады в один стек монад? Какой есть способ, минимизирующий церемонии и свистопляски с типами?

У тебя есть MonadState, с его помощью можно сделать такой трюк:

newtype State1 = State1 { testOne :: Int }
newtype State2 = State2 { testTwo :: Int }

workingWithTwoStates :: (MonadState State1 m, MonadState State2 m) => m ()
workingWithTwoStates = do
__x <- gets testOne
__y <- gets testTwo

__let updateFirst state = state { testOne = x + y }
____updateSecond state = state { testTwo = x + y }

__modify updateFirst
__modify updateSecond

А дальше можно для твоей монады в приложении newtype MyApp a = MyApp { runMyApp :: StateT CombinedState ... } через кунг фу на deriving via и HasField автоматически вывести MonadState State1 и MonadState State2, которые являются полями в CombinedState
Аноним 21/04/21 Срд 20:54:31 2003808192
>>2003757
Либо сделать самый простой способ и держать всё состояния в рамках одного CombinedState и везде бегать с MonadState CombinedState m

Это тоже вариант, при этом вполне себе удобный, в особенности если запастить линзами.
Аноним 21/04/21 Срд 21:58:12 2003855193
>>2003804
> И таким образом мы знаем, что в этой функции никаких черных ходов не используется и всё что она может сделать - это вызвать одну из функций из выше перечисленных тайпклассов.
> И если на этой функции будет констрейнт MonadIO, то мы теряем вот эту возможность знать, что внутри за хрень будет происходить. Потому что это значит, что там внутри будет всё что угодно.

Я понимаю, если бы ты своё состояние держал в IORef-ах - тогда да, ты не знаешь, что там творится в этих IO-действиях: они рисуют на экране или портят состояние твоего приложения. Но если ты не используешь IORef-ы и другие штуки, изменяющиеся в IO-контексте, то в чём проблема?

Я говорю про случай, когда к твоим инструкциям нужно добавлять IO-инструкции. У тебя есть стейт и тебе нужно печатать в консоль. Стейт хранится не в IORef-ах, а в StateT. Покажи, как убрать эти чёрные ходы (если их вообще нужно убирать), при этом оставив возможность перемежать твои доменные операции с печатью в консоль.
Аноним 21/04/21 Срд 23:45:36 2003963194
MONAD.png 108Кб, 300x300
300x300
Прочитал "Learn You a Haskell for Great Good!", прошёл 1ый курс на степике, начал второй и, когда рассказывают про Alternative, я наконец-то понял, что ...
Аноним 22/04/21 Чтв 00:08:37 2003973195
>>2003963
Что за курсы на степике?
Аноним 22/04/21 Чтв 00:14:35 2003975196
>>2003973
Бесплатные видеокурсы с задачками на stepik от Дениса Москвина.
Аноним 22/04/21 Чтв 01:19:45 2004018197
100023215676b0.jpg 62Кб, 2000x1445
2000x1445
Сап, аноны. Попробовал тут запилить свой ЯП на Парсеке. Всё бы ничего, но этот самый Парсек инстанциирует хуеву тучу классов, в каждом из которых хуева туча операторов, и это не считая Prelude. По сему у меня вопрос:

Как, блядь, всё это запомнить?!

Вот прямо сейчас заглянул в доке и заменил несколько своих операторов на библиотечные. Доколе?
Аноним 22/04/21 Чтв 09:19:48 2004102198
>>2004018
Ну основные тайпклассы легко запомнить, благо их не очень много и они предельно логичные: Semigroup, Monoid, Functor, Applicative, Alternative, Monad, MonadPlus, Foldable, Traversable.

У них главное помнить про их основные функции и операторы.

Это то, что используется везде и в целом имеет достаточно логичные операторы и логику. Для каждого из них есть ещё куча всяких интересных комбинаторов, но их можно не запоминать, а использовать hoogle и typed holes, чтобы находить их по мере надобности.

Дальше идут всякие MTL типа MonadReader, но в них всё просто и обычно аналогично функциям соответствующего трансформера.

Ещё можно помнить про Arrow и т.п., но комбинаторы оттуда не очень часто используются, так что это на любителя.

Ну и инфраструктурные тайпклассы наверное надо помнить: всякие Coercible, HasField, IsLabel, Generic и т.п. А то на них сейчас в экосистеме очень много всего построено.
Аноним 22/04/21 Чтв 09:57:05 2004123199
>>2003855
> Но если ты не используешь IORef-ы и другие штуки, изменяющиеся в IO-контексте, то в чём проблема?

Проблема в том, что тогда любому умнику работающему в этой код базе ничего не помещает сделать такой ход конём:

myDomainFunction :: MyDomainMonad DomainType
myDomainFunction = do
__doSomething ...
__-- здесь у нас куча бизнесовой логики
__-- а потом какой-нибудь умник вставляет сюда
__runIO launchMissiles
__-- и всё, мы теперь даже никак не узнаем, что у нас тут вообще какие-то unrestricted побочные эффекты
__-- потому что сигнатура функции не поменялась

И нафига нам тогда эрзац система эффектов в виде фри монад, если никакой пользы как система эффектов она не несёт и никакие эффекты не трекает?

Тестируемости ради? Так не проще тогда бегать с рекордами функций и ReaderT паттерном? Оно настолько же тестируемо, только при этом перформанс показывает порядком лучше и не требует бойлерплейта с интерпретаторами и т.п.
Аноним 22/04/21 Чтв 14:28:11 2004426200
>>2004123
Если ты знаешь заранее, и можешь перечислить, какие IO-операции будут вызываться вместе с твоими доменными операциями, можно для этих IO-операций создать отдельную ограничительную монаду, тогда невозможно будет вызвать launchMissiles.

Но если ты заранее не знаешь, какие IO-операции понадобятся вызывающему коду, то такую ограничительную монаду объявить не получится. Но я не вижу в этом проблемы, потому что именно это и нужно написать: нужно дать возможность вызывающему коду вызвать любую IO-операцию, в том числе и launchMissiles. Вызывать launchMissiles или не вызывать - это уже отвественность вызывающего кода, а не твоя.
Аноним 22/04/21 Чтв 14:42:34 2004434201
>>2004426
> тогда невозможно будет вызвать launchMissiles.
Хотя, можно создать инстанс ограничительной монады для IO, и в реализации какой-нибудь операции вызвать launchMissiles, но я думаю такой код будет бросаться в глаза.

Есть ли какой-нибудь способ исключить возможность вызова launchMissiles, но при этом чтобы была возможность вызывать нужные тебе IO-операции?

Короче, получается такой разговор: ты говоришь "IO плохо", я говорю: "да, IO плохо, но оно нужно", потом я спрашиваю "как сделать так, чтобы вызывались только нужные тебе IO-операции?", а ты отвечаешь "IO плохо".
Аноним 22/04/21 Чтв 14:49:18 2004439202
>>2004123
> И нафига нам тогда эрзац система эффектов в виде фри монад, если никакой пользы как система эффектов она не несёт и никакие эффекты не трекает?
Для удобства, плюс эти эффекты могут делать всё что угодно, но если ты не хранишь состояние приложения в IORef-ах, то состояние они не меняют.

Зачем в ORM-ах нужны всякие DSL создания запросов, если там есть функция запуска запроса из строки? Ответ: для удобства.

А если знаешь подход получше, то опиши его.
Аноним 22/04/21 Чтв 15:15:23 2004470203
>>2004102
Хм, их действительно немного. Похоже, у меня проблема не с запоминанием, а с пониманием, что эти операции делают. Я могу воспроизвести по памяти законы, например, для Semigroup, но я не могу понять, как из них следует, что (<>) - это конкатенация списков и ничто другое. Монадами я вообще могу пользоваться в do-нотации. Как вы это понимаете всё?
Аноним 22/04/21 Чтв 15:20:33 2004477204
>>2004434
> Хотя, можно создать инстанс ограничительной монады для IO
Можно создать ограничительную монаду, основанную на IO, сделать так, чтобы она не была тайпклассом и не была инстансом MonadIO. Получается такой список операций, который невозможно расширить, можно только вызывать операции.

>>2004439
> А если знаешь подход получше, то опиши его.
До этого ты упоминал про преимущество таглесс файнал стиля, что можно отличать функции, использующие IO-операций, от тех, которые не используют их. В принципе можно согласиться, но это просто способ отмечать функции, ведь всё равно возможность вызвать launchMissiles не исключается.
Аноним 22/04/21 Чтв 15:30:33 2004494205
>>2004434
Ну да, ты прячешь всё нужные операции за своими тайпклассами, пишешь код как:
myDomain :: (HasDb m, HasPrint m, ...) => m MyType

И дальше реализуешь для своего монадического стэка который на краю приложения в качестве m в такие функции втыкается
Аноним 22/04/21 Чтв 16:07:21 2004537206
Как в хаскелле обстоят дела с GUI? Есть нормальные игровые движки?
Аноним 22/04/21 Чтв 16:18:41 2004551207
>>2004537
> Как в хаскелле обстоят дела с GUI?

Биндинги к GTK, Qt и wxWidgets

> Есть нормальные игровые движки?

Ну движков большого уровня нет, а так кажется, что гонять игры на ленивом языке - это рискованное занятие.
Аноним 22/04/21 Чтв 16:20:31 2004555208
>>2004551
> а так кажется, что гонять игры на ленивом языке - это рискованное занятие.
Получится так, что вся программа это одна большая монада?
Аноним 22/04/21 Чтв 16:25:19 2004560209
>>2004555
Нет, проблема не в этом. Будет много борьбы с тем, что лэтенси нужный для игр стабильно держать.
Аноним 22/04/21 Чтв 16:27:16 2004565210
>>2004560
> лэтенси
Что это значит в контексте обсуждения?
Аноним 22/04/21 Чтв 16:35:51 2004574211
>>2004565
В данном случае речь про то, что может быть сложно стабильно держать 16 мс на кадр в языке с ленивыми вычислениями и сборщиком мусора.
Аноним 23/04/21 Птн 02:16:45 2005125212
16191332524180.jpg 41Кб, 600x600
600x600
Если бы вы только знали как всё плохо на самом деле.
Аноним 23/04/21 Птн 04:26:51 2005161213
>>2005125
Не надо говорить, что всё плохо. Скажи лучше, что всё хорошо.
Аноним 23/04/21 Птн 08:24:05 2005210214
>>2005161
ООП идиоты повсюду и проникли во все сферы нашей жизни.
Аноним 23/04/21 Птн 08:40:19 2005214215
>>2005210
А ведь ООП это всего лишь подмножество того, что может ФП.
Аноним 23/04/21 Птн 08:45:41 2005216216
>>2005214
ФП это подмножество брайнфака.
Аноним 23/04/21 Птн 08:52:04 2005218217
>>2005216
Нихуя. Лямбда хоть и эквивалентна брейнфаку, но не равна ему. Это принципально разные языки, не нельзя их отнести как подмножества/надмножества к друг-другу.
Аноним 23/04/21 Птн 08:55:01 2005219218
>>2005218
>подмножества/надмножества
Значение знаешь?
Из хаскеля в брайнфак изоморфизм можно написать. Хаскель подмножество брайнфака, а брайнфак подмножество хаскеля.
Аноним 23/04/21 Птн 09:55:35 2005236219
>>2005219
Ну давай, напиши source-to-source transpiler из хаскелла в брейнфак, а я погляжу.
Аноним 23/04/21 Птн 10:19:11 2005246220
>>2005236
Достаточно сделать транспайлер из C- или бакенд для LLVM. И не получится портировать System.IO и прочее.
Аноним 23/04/21 Птн 10:32:21 2005263221
>>2005236
И то и то полное по Тьюрингу. Я же говорю, вы не представляете как всё плохо на самом деле.
Аноним 23/04/21 Птн 10:41:04 2005272222
>>2005246
>И не получится портировать System.IO и прочее.
Win32 под линупс написали. А тут какая то библиотека от никому не нужного языка(читай маленькая).
Аноним 23/04/21 Птн 11:20:05 2005337223
>>2005272
Вы не понимаете, это другое.

В POSIX больше тысячи системных вызовов, в BF-машине - 4, два из которых - это управление потоком выполнения.
Аноним 24/04/21 Суб 18:43:00 2007220224
>>2004470
(<>) в полугруппе это бинарная операция с типом a -> a -> a, которая чем-то похожа на сложение, только в более широком смысле. Какая функция у нас складывает два списка, получая третий?
Аноним 24/04/21 Суб 21:07:12 2007392225
>>2007220
Двачую этого господина и хочу поделиться статьей которая как помне хорошо описывает что такое semigroup на интуитивном уровне.
http://www.tomharding.me/2017/03/13/fantas-eel-and-specification-4/

Вообще советую всю серию, хоть примеры в джс, сама суть помогла понять лучше картину алгебраических структур
http://www.tomharding.me/fantasy-land/
Аноним 26/04/21 Пнд 12:58:15 2009071226
>>2007392
>хорошо описывает что такое semigroup на интуитивном уровне.

>>2005125
Аноним 01/05/21 Суб 02:16:34 2014619227
Аноним 01/05/21 Суб 02:55:34 2014621228
Аноним 01/05/21 Суб 02:57:49 2014622229
Аноним 01/05/21 Суб 13:00:38 2014926230
>>2014622
Спасибо! А это какого числа версия, я только метку 2018 гор увидел, но полная же позже вышла?
Аноним 01/05/21 Суб 14:03:54 2014961231
>>2005214
Наоборот, HM и System F - это подмножество сабтайпинга.
Аноним 01/05/21 Суб 16:33:14 2015129232
>>2014961
ООП и сабтайпинг это разные вещи. ООП это вообще цирк, не имеющий никаких математических основ.
Аноним 01/05/21 Суб 18:50:14 2015432233
Аноним 02/05/21 Вск 01:12:38 2015930234
>>2015129
>не имеющий никаких математических основ
А вот здесь поподробнее, пожалуйста. Что ещё за "математические основы"? В каком смысле вы используете этот термин? Статический анализ ООП-кода возможен, формальная верификация - тоже. Что вам ещё нужно?
Аноним 02/05/21 Вск 01:32:23 2015938235
>>2015930
Сама концепция ООП в том виде, что она есть сейчас, - императивщина неверифицируемая. Попробуй статично проанализировать мутирующий в рантайме код, а я погляжу.
Аноним 02/05/21 Вск 01:48:22 2015946236
>>2015938
То есть "математические основы" - это какой-то ваш собственный термин, а не что-то конкретное.
Аноним 02/05/21 Вск 10:24:41 2016136237
>>2015946
Это теория категорий. Программа на Хаскеле пруфабельна, ООП код нет.
Аноним 02/05/21 Вск 11:20:15 2016164238
>>2016136
Хачкель может пруфануть что приложение будет коммерчески успешным?
Аноним 02/05/21 Вск 12:34:22 2016205239
>>2016164
Как ООП и комерческая успешность связаны? Клиенту похуй, на чем написано. Главное чтобы работало быстро и был красивый UI.
Аноним 03/05/21 Пнд 02:47:17 2017125240
>>2000690
> А что ты скажешь о том простом факте что твой фп-код под капотом превращается в код на императивном C
Не превращается. Ghc не транслятор.
Аноним 03/05/21 Пнд 03:30:47 2017142241
ebedd6dd0d783db[...].jpg 61Кб, 563x561
563x561
>>2016136
Хаскель никак не использует теорию категорий.

1. Hask не является категорией. Аксиоматика требует, чтобы undefined . id = undefined, однако это не выполняется. Hask похожа на категорию, но является чем-то другим.

2. Понятия из теории категорий не используются в языке. Так, в хаскелле нельзя определить произвольную категорию. Всё рассматриваемое должно быть "подкатегорией" Hask и определяться неявно. Поскольку Hask не является категорией, категорий в языке нет вообще. Аналогично, нельзя определить произвольный функтор. Всё, что есть, - "эндофункторы" Hask. Которые не эндофункторы.

3. Программисты на хаскелле не знают теорию категорий. Я соглашусь, что itt определить категорию более-менее смогут все (впрочем, наверняка забыв про парочку требований). Возможно, смогут определить и функтор, и даже естественное преобразование. Однако сопряженные функторы уже не будут определены. И у меня есть твёрдая уверенность, что ни теорему Фрейда о сопряженных функторах, ни теорему Бека, ни даже теорему Майлейна-Эйленберга о конкретизируемости никто itt не сможет не то что доказать, но даже сформулировать. Ин факт, я думаю, что люди здесь названия этих теорем не слышали никогда.

Производные категории? Локали и фреймы? Превратные пучки? Всё это - базовые вещи теорката - абсолютно не нужно для программирования на хаскелле, абсолютно никак не используется и никогда не упоминается.

Заимствовать несколько стартовых определений (причем по аналогии, а не в точном смысле) - это не то же самое, что использовать теорию категорий. Математическая теория - это про теоремы, а не про определения. Нет смысла в заимствовании определений, если не заимствуются теоремы.

Тут хотя бы методичку Маклейна кто-нибудь прочитал вообще?
Аноним 03/05/21 Пнд 09:58:19 2017265242
>>2017142
Почему тогда математикам, любящим теорию категорий, нравится хаскелл?
Аноним 03/05/21 Пнд 12:24:23 2017402243
>>2017142
Hask - это библиотека такая или часть языка?
Аноним 03/05/21 Пнд 12:35:31 2017413244
Аноним 03/05/21 Пнд 20:31:28 2017910245
>>2017265
Потому что чувак несет шизоидную хуйню. Никто не говорит что 1 в 1 код превращается в категории, но идея и многие правила идут оттуда.
Аноним 03/05/21 Пнд 21:02:47 2017963246
>>2017910
>мы используем теорию категорий
>не используете, вот, смотрите
>зато у нас идея
Аноним 04/05/21 Втр 11:32:26 2018730247
Аноним 04/05/21 Втр 18:51:37 2019369248
Вот в хаскеле есть функция (<-).
Как определить подобную функцию?
Аноним 04/05/21 Втр 20:07:27 2019435249
Аноним 04/05/21 Втр 20:32:03 2019460250
>>2019435
А в языке должно быть что-то кроме функций?
Аноним 04/05/21 Втр 20:51:23 2019479251
>>2019460
Если говорить о функциях, то тогда есть функция (>>=). Синтаксический сахар, использующий (<-) эквивалентен вызовам (>>=).
Аноним 05/05/21 Срд 22:11:26 2020882252
Прохожу курс по теории категорий, подводные камни?
Аноним 05/05/21 Срд 22:19:17 2020894253
>>2020882
>подводные
Это категория.
Аноним 06/05/21 Чтв 20:33:05 2022106254
Screenshot from[...].png 109Кб, 768x703
768x703
Мемные вакансии появляются уже в России.
Аноним 06/05/21 Чтв 21:16:04 2022134255
В чём разница между классом и множеством?
Аноним 06/05/21 Чтв 21:21:33 2022143256
>>2022134
Лучше бы задал вопрос: «В чем разница между типом и множеством».
Аноним 06/05/21 Чтв 21:30:33 2022157257
>>2022134
Ни в чем.

Класс это тип. А типы в прогоаммировании это представление наивной теории множеств.
Аноним 06/05/21 Чтв 22:25:19 2022208258
>>2022157
Я не совсем о программировании. Категория задаётся как класс объектов + морфизмы + ассоциативный закон. Почему ввели новое слово класс, почему не множество объектов?

> A category C consists of the following three mathematical entities:
> A class ob(C), whose elements are called objects;
> ...

https://en.wikipedia.org/wiki/Class_(set_theory)

Почему натуральные числа нельзя назвать множеством? Там в статье как раз приводится что это не множество, а proper class.
Аноним 06/05/21 Чтв 23:43:52 2022291259
Screenshot20210[...].jpg 323Кб, 720x1520
720x1520
>>2022208
Потому что не все обьекты/морфизмы можно впихнуть в множество. Банальный пример - категория Set. В ней обьекты это все множества, а как известно, множества всех множеств не существует, то придумали классы.
Как я понимаю, только в малых категориях вместо класса может быть множество.
Аноним 07/05/21 Птн 00:25:39 2022349260
>>2022291
> class of all ordinal numbers
Всё, я понял. Если natural numbers ещё можно назвать set, хотя они и бесконечные, то ordinal numbers это больше чем natural numbers и для каждого бесконечного множества можно иметь бесконечное количество вариантов упорядочиваний.
Аноним 07/05/21 Птн 00:38:07 2022370261
1323499520.png 71Кб, 240x343
240x343
>>2022291
> а как известно, множества всех множеств не существует
Ахах. Учи математику, чтобы не быть батхертом.
Аноним 07/05/21 Птн 00:39:44 2022374262
>>2022349
> Если natural numbers ещё можно назвать set, хотя они и бесконечные
В теориях множеств, множества могут быть бесконечными.
Аноним 07/05/21 Птн 00:45:24 2022380263
>>2022291
Пиздос, как же там всё глубоко оказывается. Теорию множеств порезали в аксиоматике чтобы разрешить парадокс Рассела, который нахер ломает математическую логику и доказывает что истина эквивалентна лжи. Вот то что отрезали от теории множеств, это и есть proper classes.

Это просто прекрасно:

> Most sets commonly encountered are not members of themselves. For example, consider the set of all squares in the plane. This set is not itself a square in the plane, thus it is not a member of itself. Let us call a set "normal" if it is not a member of itself, and "abnormal" if it is a member of itself. Clearly every set must be either normal or abnormal. The set of squares in the plane is normal. In contrast, the complementary set that contains everything which is not a square in the plane is itself not a square in the plane, and so it is one of its own members and is therefore abnormal.

> Now we consider the set of all normal sets, R, and try to determine whether R is normal or abnormal. If R were normal, it would be contained in the set of all normal sets (itself), and therefore be abnormal; on the other hand if R were abnormal, it would not be contained in the set of all normal sets (itself), and therefore be normal. This leads to the conclusion that R is neither normal nor abnormal: Russell's paradox.

Просто человеческий язык слишком гибкий и позволяет придумать такие штуки, которые всё ломают.
Аноним 07/05/21 Птн 00:50:47 2022384264
>>2022380
А ты отверги эту аксиому и развивай свою. Глядишь чего ещё нового интересного получится.
Аноним 07/05/21 Птн 04:14:14 2022441265
Мне не хватает навыка писать в функциональном стиле. С одной стороны получается задачки решать, но с другой остаётся ощущение будто бы я как обезьяна покрутил гранатой, оно кое-как скомпилировалось, попереставлял . $ () чтобы функции сложились как надо, и готово. Я не могу например в голове разворачивать всё что происходит внутри IO монад, хоть я и прочитал статью что там внутри происходит, но как-то сразу глядя на код сказать куда и во что всё выполнится не могу. Это всё с практикой пройдёт или нужно что-то ещё такое скурить фундаментальное чтобы мозг вставить в нужную позицию?
Аноним 07/05/21 Птн 04:19:47 2022442266
>>2022441
К примеру, делаю так

myButLast [x,_] = x
myButLast (x:xs) = myButLast xs
evalAndPrint a = putStrLn . show . myButLast $ a

А потом нужна функция двух переменных

elementAt (x:xs) 1 = x
elementAt (x:xs) index = elementAt xs (index - 1)
evalAndPrint a b = putStrLn . show $ elementAt a b

И putStrLn . show . elementAt $ a b уже не работает, потому что оператор композиции имеет тип (.) :: (b -> c) -> (a -> b) -> a -> c Можно конечно ещё написать putStrLn . show . (elementAt a) $ b но это как-то совсем неочевидно.

Что характерно, в первом примере я не могу сделать
evalAndPrint = putStrLn . show . myButLast
Нужно обязательно параметр указать, хотя казалось бы, композиция должна уметь это делать. Возможно просто не хватает явной сигнатуры, но это всё очень неочевидно.
Аноним 07/05/21 Птн 04:46:58 2022447267
>>2022442
> И putStrLn . show . elementAt $ a b уже не работает
Это ведь означает (putStrLn . show . elementAt) $ (a b), как будто а - функция, принимающая b в качестве параметра.

Какие-то сомнительные примеры. Мне кажется, evalAndPrint без параметра должен компилиться, только лень проверять.
Аноним 07/05/21 Птн 05:06:11 2022452268
Screenshot from[...].png 32Кб, 833x212
833x212
>>2022447
Ну ладно, operator precedence это везде боль, надо привыкать. Но второе не собирается, почему-то ему хочется больше инфы про типы.
Аноним 07/05/21 Птн 08:49:51 2022502269
>>2022134
Класс - это совокупность каких-то вещей.
Множествами называются классы, которые могут быть элементами других классов.
Собственные классы, или большие классы, - это классы, которые не могут быть элементами других классов.

Например, совокупность натуральных чисел - множество. Совокупность всех множеств - большой класс, но не множество. Подробнее см. в учебнике по NBG.

>>2022291
Mor C - совокупность всех стрелок категории C.
HomС(A,B) - совокупность всех стрелок из A в B в категории C.
Mor - объединение всех Hom'ов.

Малые категории - у которых Mor является множеством.
Локально малые - у которых любой Hom является множеством, но Mor может не являться множеством.
Большие категории - у которых хотя бы один из Hom'ов не множество.

Всякая малая категория также и локально малая, разумеется.

>>2022370
В классических теориях множеств (Z, ZF, ZFC и популярные дополнительные аксиомы для ZF, NBG, MK) совокупность всех множеств не является множеством. В NF и NFU множество всех множеств таки есть, но нельзя доказать, что оно является моделью NFU.

>>2022380
>истина эквивалентна лжи
Из противоречия следует вообще какое угодно утверждение, не только 1=0.
Аноним 07/05/21 Птн 17:38:11 2023213270
>>2022502
> вообще какое угодно утверждение
Если быть точным, то из него следует неконсистентность теории.
Аноним 07/05/21 Птн 17:47:48 2023234271
>>2023213
Именно любое утверждение. Пусть доказаны A и ¬A, и пусть B - произвольное утверждение.
1. A # по условию
2. ¬A # по условию
3. ¬A→¬A∨B # аксиома
4. ¬A∨B # Modus Ponens к 2 и 3
5. ¬A∨B ⇔ A→B # известная теорема об импликации
6. A→B # MP к 4 и 5
7. B # MP к 1 и 6
чтд
Аноним 07/05/21 Птн 18:57:06 2023324272
>>2023234
А более понятно можешь все эти пункты объяснить? Explain like I'm five.
Аноним 07/05/21 Птн 19:21:41 2023346273
unnamed (4).jpg 49Кб, 512x360
512x360
>>2023324
Эти пункты - логический вывод в обычном исчислении высказываний. В выводе каждый пункт должен быть либо аксиомой, либо ранее доказанной теоремой, либо получаться из каких-то предыдущих пунктов по правилу Modus Ponens. Правило Modus Ponens (MP): если выведены утверждения X и X→Y, то следует считать выведенным утверждение Y.

Значок ¬ означает "не". Пункты 1 и 2 - обнаруженное противоречие. Значок ∨ означает "или". Пункт 3 - логическая аксиома: какими бы ни были утверждения X и Y, следует считать выведенным утверждение X→X∨Y. В качестве X взято утверждение "не A", в качестве Y - пока что не доказанное утверждение B.

Значок → означает импликацию, связку "если ... то ...". Пункт 5 - теорема об импликации. Теорема говорит, что утверждение "¬A∨B" эквивалентно утверждению "A→B". Убедиться в справедливости теоремы можно, сравнив таблицы истинности для этих двух утверждений.

6 и 7, наверное, понятны.
Аноним 07/05/21 Птн 19:29:58 2023350274
>>2023346
Например, пусть A - "небо синее", ¬A - "небо не синее", B - "луна сделана из сыра".
Тогда вывод будет следующим.

1. Небо синее
2. Небо не синее
3. Если небо не синее, то небо не синее или луна сделана из сыра.
4. По п.2 небо не синее, и имеем: небо не синее или луна сделана из сыра.
5. То, что небо не синее или луна сделана из сыра, равносильно тому, что: если небо синее, то луна сделана из сыра.
6. Итак, если небо синее, то луна сделана из сыра.
7. По п.1 небо синее, и имеем: луна сделана из сыра.

Самый неинтуитивный момент здесь - эквивалентность ¬A∨B ⇔ A→B.
Дело в том, что утверждение "если A, то B" ложно лишь в одном случае: когда A истинно, а B ложно. А во всех остальных случаях это утверждение истинное, что и даёт эквивалентность. При этом между A и B может не быть никакой смысловой связи. Если интересно, почему так получилось, то можно посмотреть учебник матлогики или статью https://ru.wikipedia.org/wiki/Парадокс_импликации
Аноним 07/05/21 Птн 19:50:46 2023370275
>>2023346
>>2023350
Спасибо, теперь понятно. Да, действительно, теорема об импликации - неинтуитивная штука. Но, с другой стороны, противоречия тоже неинтуитивны, хотя может быть бывают разные уровни интуиции, и на каком-то уровне интуиция признаёт противоречия и бессилие разума перед ними. Только куда дальше двигаться с этой точки? Релятивизм? Придумывать себе свою субъективную истину?
Аноним 07/05/21 Птн 20:04:04 2023376276
Бамп
Аноним 07/05/21 Птн 20:19:54 2023382277
>>2023370
Если в теории найдено противоречие, то теорию нужно выкинуть и сделать новую теорию. Заменить одну какую-нибудь аксиому или вообще все.
Аноним 07/05/21 Птн 21:53:58 2023457278
>>2022502
> Из противоречия следует вообще какое угодно утверждение, не только 1=0.
В общем-то говоря, если мы скажем в Wolfram Mathematica или в Prolog'e, что
1 = 0, то это будет истиной, а обратное - ложью.

Можно сказать, что 1 + 2 = 4, и это будет одной из бесконечного множества алгебр.

Математика это наука об абстракциях, здесь нет ничего априорного, кроме редукции и эквивалентности.
Аноним 08/05/21 Суб 01:38:46 2023667279
>>2023457
Не удивлюсь, если в будущем найдут что-то, что через подобные базисы можно описать.
Аноним 08/05/21 Суб 08:55:46 2023746280
>>2023457
Речь шла не об арифметике, а об эквивалентности ⊤⇔⊥.
Аноним 08/05/21 Суб 10:25:23 2023796281
>>2023746
> Речь шла не об арифметике
Я клоню к тому, что единственными аксиомами в математике являются равенство и эквивалентность (она же редукция), потому что у них нет определения. У все остальное определяется через эти две аксиомы.
> ⊤⇔⊥
Мы вправе объявить "всё = ничто", однако тогда может оказаться ложными множество полезных для нас теорий.
Аноним 08/05/21 Суб 11:08:37 2023829282
>>2023796
Возможно, тебе стоит прочитать хотя бы парочку учебников матлогики.
Аноним 09/05/21 Вск 00:46:24 2024960283
>>2023370
Отвечаю на свой пост. Я написал:
> Но, с другой стороны, противоречия тоже неинтуитивны
и ещё про
> противоречия и бессилие разума перед ними
а потом задумался: действительно ли противоречия неинтуитивны? Может наоборот? Человек мыслит противоречиво, это только потом, в какой-то момент, он узнаёт, что есть логика, что противоречия - это как бы плохо и их нужно устранять, но это просто тонкий слой какой-то культурной надстройки, а под этим слоем кроется противоречивое и парадоксальное подсознательное мышление. Да даже этот слой не мешает людям в противоречивые параграфы.
Аноним 09/05/21 Вск 01:38:35 2025013284
>>2017142
>Hask не является категорией. Аксиоматика требует, чтобы undefined . id = undefined, однако это не выполняется. Hask похожа на категорию, но является чем-то другим.

Разумеется, как и в любом тьюринг-полном языке, в Хаскеле любой тип - это не просто тип, а тип + ⊥. Т.е. жопа встроена в Int, в Bool, в небо и даже в Аллаха. Это ломает базовую аксиоматику.

Жопу из семантики тьюринг-полного языка просто так не выкинуть. Для этого, как минимум, потребуется гарантировать остановку, что автоматически сделает язык не тьюринг-полным.

Но является ли это чем-то плохим? На практике, ты не захочешь, чтобы твоя программа вычисляла жопу. Если твоя программа попробует её вычислить, она любо пизданётся с исключением либо зависнет. Т.е. любая корректная программа работает c Hask именно как с категорией.

То, что Hask, строго говоря, не является категорией на уровне семантики языка, то уж извини, это плата за тьюринг-полноту. GHC - не Б-х, он не сможет отсечь все некорректные программы, одновременно оставив возможность написать любую корректную. Это просто инструмент, тут правильнее говорить о том насколько он близок к идеалу по сравнению с другими инструментами, понятное дело, в полном смысле он никогда не будет идеальным.
Аноним 09/05/21 Вск 05:30:25 2025118285
(5::Integer) <> (7::Integer)

<interactive>:113:1: error:
• No instance for (Semigroup Integer) arising from a use of ‘<>’

Почему целые числа не образуют полугруппу в хаскеле?
Аноним 09/05/21 Вск 06:07:01 2025126286
>>2025118
Потому что можно придумать много полугрупп над полем целых чисел. Ты какую полугруппу хочешь? Min, Max, Sum? В Хаскеле все они есть, можно и свою определить, если библиотечных не хватает.
Аноним 09/05/21 Вск 07:21:05 2025136287
>>2025126
Почему тогда списки/строки имеют некий дефолт в Semigroup? Разве там нельзя придумать альтернативный оператор?
Аноним 09/05/21 Вск 07:40:41 2025138288
Не понимаю что значит моноид в категории эндофункторов. Вот я понял что такое моноид, что такое категория и что такое эндофунктор. Но сложить вместе почему-то не получается. Вот если объекты категории это эндофункторы, то что в ней морфизмы? Для моноида нужна некоторая операция, где мы её взяли? Объекты моноида это всё те же эндофункторы? Интуитивно выходит что мы как бы сворачиваем, фолдим функторы не выходя за пределы какой-то категории. Но тут ведь можно представить категорию эндофункторов как вообще все возможные эндофункторы из разных категорий.
Аноним 09/05/21 Вск 11:18:51 2025313289
diag1.png 171Кб, 1530x913
1530x913
diag2.png 238Кб, 1500x822
1500x822
>>2025013
Поэтому хаскель не использует теорию категорий. Используется что-то, что похоже на теорию категорий, но не является теорией категорий. Что именно - большой вопрос. Образования вроде Hask в теоркате не встречаются.

>>2025138
Ещё тебе нужно узнать, что такое естественное преобразование ака функторный морфизм. Морфизмы категории эндофункторов - естественные преобразования.

Моноид в категории эндофункторов - не то же самое, что моноид. Моноид в обычном смысле - это непустое множество с ассоциативной бинарной операцией ×, у которой есть нейтральный элемент.

А моноид в категории эндофункторов C получается следующим образом. Во-первых, множество заменяется на функтор T:C→C; о точках множества, таким образом, перестают думать. Во-вторых, композиция заменяется некоторым естественным преобразованием из T×T в T, здесь T×T = T2 - двукратное применение функтора T. В-третьих, нейтральный элемент заменяется некоторым естественным преобразованием из 1C в T, здесь 1C = id C - тождественный функтор для C. Во множестве M нейтральный элемент можно выделить с помощью отображения из 1 в M, где 1 - одноэлементное множество; в определении моноида в категории происходит нечто похожее. Наконец, на эти два естественных преобразования накладывается условие: должны быть коммутативны диаграммы пикрелейтед. Выражающие суть ассоциативности и нейтрального элемента.
Аноним 09/05/21 Вск 13:05:57 2025482290
>>2025313
А теперь быстро пишешь, где это может пригодиться в энтерпрайзе
Аноним 09/05/21 Вск 13:11:02 2025498291
Аноним 09/05/21 Вск 14:45:44 2025654292
>>2025482
Можно, наконец, выкинуть "паттерны" вроде Factory вместе с остальными достижениями индусов из области набора латиницы на клавиатуре и использовать простые и понятные для нормального человека понятия, вроде тайпклассов.
Аноним 09/05/21 Вск 14:48:34 2025657293
Аноним 09/05/21 Вск 16:03:52 2025774294
>>2025657
А зачем? Классической первопорядковой логики предикатов хватит всем, нет причин вводить искусственные костыли ради сохранения противоречий. Противоречия можно просто устранять.
Аноним 09/05/21 Вск 17:50:14 2025871295
>>2015930
> А вот здесь поподробнее, пожалуйста. Что ещё за "математические основы"?
Это когда ты рассматриваешь код как некую математическую формулу из некоей формальной теории и рассуждаешь о нём, используя математический аппарат.

В ОО языках эта формальная теория придумана с нуля безграмотными слесарями и описана выражениями вида "Return centered in a string of length width. Padding is done using the specified fillchar (default is an ASCII space). The original string is returned if width is less than or equal to len(s).", к которым проще применять не математический аппарат, а эмоциональный.
Аноним 09/05/21 Вск 18:35:41 2025927296
Аноним 10/05/21 Пнд 10:15:40 2026353297
flow.png 9Кб, 427x355
427x355
>>2025871
Теория от слесарей конечно хуже, но тоже вполне работает. Самое главное она легко понятна другим слесарям. Обучение вполне вписывается в поток и всё познаётся от простого к сложному. Суперабстракции нужны только через год-два практики.

А в хаскеле ты просто сразу на хуй с порога идёшь разбираться с теорией категорий, просто потому что много концептов в языке решили назвать терминами оттуда по аналогии. Сюда же накладывается сложная система типов, само по себе ФП где всё наизнанку вывернуто и компилятор/рантайм по сути перекручивают AST туда-сюда вместо явной последовательности действий. Даже стека вызовов нет.

Несмотря на обилие книг, статей, на обширную вики и кучу ответов на SO, в хаскеле до сих пор нет нормального туториала от простого к сложному, включая нормальное объяснение нахуя козе баян в виде всех этих категорий монад и функторов. Вот только здесь более-менее поясняется https://www.haskellforall.com/2012/08/the-category-design-pattern.html
Аноним 10/05/21 Пнд 11:27:54 2026393298
15769223933200.jpg 62Кб, 889x611
889x611
>>2026353
> идёшь разбираться с теорией категорий
На самом деле нет, именно с теорией категорий разбираться вовсе не нужно. В том смысле, что бесполезно скачивать учебник теорката и читать его, большинство информации из такого учебника не пригодится. Из теории категорий в хаскеле только категория, морфизм, функтор, естественное преобразование, монады, сопряжения, алгебры, категория Клейсли и формализация лямбда-исчисления, никаких сложных определений и никаких теорем. Причем реально большинство людей дальше функторов по этой цепочке не продвигаются. А какой-нибудь zygohistomorphic prepromorphism - внутренний мем хаскеля, в теории категорий таких штук нет.
Аноним 10/05/21 Пнд 13:13:24 2026459299
>>2026353
Курс на степике нормально базу дает че ты епта
Аноним 10/05/21 Пнд 18:26:48 2026696300
>>2025927
Про Хаскель никто и не говорил. Но даже о хаскелекоде рассуждать проще можно, в отличие от питонокода.

>>2026353
> Теория от слесарей конечно хуже, но тоже вполне работает.
Каждый человек - немножко шеф-повар.
Аноним 10/05/21 Пнд 20:32:08 2026923301
Аноним 10/05/21 Пнд 20:51:25 2026942302
Когда и откуда пошло называть хаскелистов штангистами?
Аноним 10/05/21 Пнд 21:54:28 2027011303
>>2026942
С хаскелиста-штангиста, живущего с мамкой
Аноним 11/05/21 Втр 06:47:21 2027271304
>>2026942
С хаскелиста, который засовывал себе штангу в зад
Аноним 14/05/21 Птн 19:22:01 2030789305
tenet.mp4 1715Кб, 1280x720, 00:00:23
1280x720
У меня есть моноид над множеством целых чисел с операцией умножения. В этом моноиде есть волшебный элемент 0. Потому что 0x = x0 = 0. Как называется этот элемент? Как называются моноиды, содержащие подобный элемент (потому что моноид с операцией сложения, такого, например не содержит).
Аноним 14/05/21 Птн 19:34:25 2030825306
Нашёл уже, можете не отвечать.
Аноним 14/05/21 Птн 20:18:37 2030876307
>>2030789
> (потому что моноид с операцией сложения, такого, например не содержит)
С хуя ли не содержит?

data Nat = S Nat | Z
S x + y = x + S y
Z + x = x
x + Z = x
Аноним 14/05/21 Птн 20:40:30 2030903308
>>2030876
это нейтральный элемент, я писал про абсорбирующий.
Аноним 14/05/21 Птн 20:45:32 2030905309
>>2030903
Т. е такой, что при аппликации к нему, (вне зависимости от остальных аргументов) возвращается он сам?
x Z = Z
Z
x = Z

Тащемта можно создать обобщонную функцию, которая выражает все подобные функции над любым количеством аргументов.
Аноним 15/05/21 Суб 17:20:28 2031481310
Как лучше сделать сайт на хаскеле? Целиком все на хаскеле, или всё, что можно, пустить через nginx, а в хаскеле оставить только логику и какое-нибудь RPC (то же JSON API)?
Аноним 15/05/21 Суб 18:16:54 2031522311
А, можно же всегда ngingx сверху накрутить. Я идиот. Спасибо, анон.
Аноним 15/05/21 Суб 18:42:49 2031547312
>>2031522
Всегда пожалуйста, анон.
Аноним 15/05/21 Суб 21:08:54 2031676313
>>2030789
Моноид с нулём часто так и называется — моноид с нулём.
Аноним 15/05/21 Суб 21:09:38 2031677314
Причём может быть только с левым или только с правым нулём или и с тем и другим
Аноним 15/05/21 Суб 21:14:43 2031687315
>>2025136
Дефолтным является самый распространённый юзкейс (конкатенация)

Над целыми числами просто нет явного «дефолтного» юзкейса
Какой выберешь, сложение или умножение?
Аноним 15/05/21 Суб 22:46:10 2031755316
Аноним 16/05/21 Вск 15:17:34 2032383317
>>2031755
Ну NaN это просто ещё один ноль в этом случае
Аноним 16/05/21 Вск 21:13:08 2032758318
Аноним 18/05/21 Втр 00:49:57 2034047319
>>2030905
>Т. е такой, что при аппликации к нему, (вне зависимости от остальных аргументов) возвращается он сам?

Тащемто да.

>Тащемта можно создать обобщонную функцию, которая выражает все подобные функции над любым количеством аргументов.

Тут бы хотелось попадробнее. Есть задача - организовать раннюю остановку программы и выразить это красиво математически. В некоторых случаях абсорбирующий элемент моноида для этого подходит. Например, мы вычисляем a & b & c & d & e.. В какой-то момент мы поняли, что выражение стало равно false, это значит, что дальше вычислять не имеет смысла, потому что всё равно стало false и при дальнейшем примерении операций false так и останется.

Но есть одна проблема.

x Z = Z
Z x = Z

подразумевает, что Z - единственный. Т.е. что Z = Z. Но у меня задача - поиск кратчайшего пути в графе. Т.е. если я нашел кратчайший путь, я могу останавливать алгоритм и выводить результат, другой путь будет точно не короче. Поэтому, в плане длинны, они эквивалентны. Но они не равны друг другу.

Это не один абсорбирующий объект, это класс объектов. Пользователю похуй какой путь найдёт программа, ему любой путь подойдёт. Но и "забывающее" отображение применить нельзя, потому что пользователю интересен сам путь, а не его длинна, которая могла бы "забыть" маршрут и уровнять все пути через их длину. Вот я думаю, можно ли эту логику впихнуть в моноид какой-нибудь.
Аноним 18/05/21 Втр 00:54:46 2034049320
>>2031481
Лучше сделай сайт на Node.js. Нахуй тебе сайт на Хаскеле, ты наебёшся по всем фронтам, начиная с хостинга, кончая программированием. Хаскель никогда не был в топчике для лепки сайтов.
Настройки X
Ответить в тред X
15000
Макс объем: 40Mб, макс кол-во файлов: 4
Кликни/брось файл/ctrl-v
Стикеры X
Избранное / Топ тредов