Ilya
Vladislav
> (Realworld -> Realworld, Int)
Какой-то неправильный тип
Ilya
она не зависит от каких-то состояний
Anonymous
unsafePerformIO
Anonymous
😀
Vladislav
И вообще модель IO a как функции RealWorld -> (a, RealWorld) я никогда не понимал, ведь мне в такой модели ничто не помешает к одному RealWorld применить разные функции, что нонсенс.
Vladislav
Нормально это моделируется только с линейными типами, в Merucry красиво сделали
Cheese
См выше
не понял, уточни направление, пожалуйста
кана
Я как-то задавал вопрос про РилВорлд, мне никто не ответил про него ничего. Я так понимаю, это какой-то кусок памяти, изменение которого сразу отражается на реальном мире (файловая система например). То есть именно РилВорлд является хаком, а не IO
Ilya
начнём с того, что ST является хаком?
Cheese
RealWorld не память, это вообще ничего. все действия с ним сводятся к вызову процедур, определённых вне Хаскелла
Vladislav
RealWorld это фантомный тег для создания data dependency
Vladislav
А на самом деле при редукции термов в Haskell могут быть сайд-эффекты, выполняемые RTS
Vladislav
И этот RealWorld позволяет порядок там навести небольшой
Vladislav
unsafePerformIO просто забивает на RealWorld
кана
Я к тому, что можно ли делать сайд-эффекты без IO? То есть можно ли на хаскеле написать свою систему для сайд-эффектов без IO-монады
Vladislav
Можно
Vladislav
Есть набор примитивов, у которых во внутренностях GHC проставлено, что они могут вызывать прерывания процессора и делать сайд-эффекты. Их перечень захардкожен. Оптимизатор аккуратно не перемещает их никуда (там два принципа перемещения, float in и float out), чтобы гарантировать, что ничто два раза не вызывается. RealWorld применяется, чтобы в правильном порядке вызывались (создавая искуственно data dependency).
Vladislav
Можно взять эти примитивы и свою систему эффектов сделать.
Vladislav
Все-таки IO это библиотечный тип, а не примитив
Евгений
А ST примитив?
Vladislav
Нет
Vladislav
ST это тот же тип, что IO, только вместо RealWorld там forall s. s, и имеем от этого runST
Ilya
понять бы ещё, как эта runST работает
Vladislav
Никак, это no-op чтобы гарантировать, что ты не пытаешься ST-переменные за пределами ST использовать
Vladislav
ST гарантирует referential transparency за счет того, что переменные локальны
Ilya
но всё-таки интересно, откуда она это начальное состояние берёт
Ilya
или на самом деле она ничего не берёт
Ilya
и это большой обман
Vladislav
Он его не берет, переменная s никогда не инстанцируется
Cheese
когда я писал «примитив», имел в виду процедуры readIORef и writeSTRef, а не типы ST или IO
Cheese
s не обман, она честно не используется
Cheese
то есть её значение
Vladislav
У нее нет значения
Ilya
интересно. то есть получается, что не все допустимые функции могут быть написаны на haskell, однако это не мешает нам их использовать, потому что из самой сигнатуры (forall s. ST s a) -> a следует, что такая функция единственна, а значит и "знать" нам её не обязательно
Ilya
а ещё такие функции есть?
Ilya
тело которых нельзя записать на языке редукции выражений
Alexander
Ilya
но которые можно юзать, и это будет непротиворечиво
Vladislav
Ilya
ну как бы выглядео тело такой функции?
Vladislav
Возьми и посмотри исходник
Vladislav
Ilya
ок
Alexander
Ilya
почему?
наверное я не прав. просто так читал в какой-то книжке, типа нач. значение берётся из ниоткуда
Alexander
Vladislav
Кстати, надо бы и мне смотреть повнимательнее. Судя по runRW#, все-таки s инстанцируется внутри, как RealWorld.
Alexander
оно размера 0
Vladislav
Так что ST еще больше похож на IO, чем я думал.
Alexander
дальше оптимизации
Alexander
В смысле что похож на ио, если ио это и есть ст
Vladislav
Я думал что IO это ST, где s принимается за RealWorld
Vladislav
а оказывается и в самом ST тоже RealWorld
Vladislav
Соответственно разница еще меньше
Alexander
как это в ст Real world?
Vladislav
Ну вон там runRW# в определении runST
Vladislav
Ilya
так, теперь надо в GHC.Magic лезть
Vladislav
Anonymous
# это просто название идентифаера?
Vladislav
Да
Alexander
действительно
Alexander
@anarchostatist обычно добавляют к функциям работающим с данными кайнда #
Alexander
unboxed
Vladislav
Этого кайнда больше нет, но традиция осталась
Anonymous
лол 🤔
Viacheslav
у меня практический вопрос, пишу обвязку вокруг api.ai
Viacheslav
{
"id": "702fcc70-aa52-4ea0-8e78-3d040e56d221",
"timestamp": "2017-09-16T12:38:33.477Z",
"lang": "ru",
"result": {
"source": "agent",
"resolvedQuery": "давай завтра",
"action": "create_task",
"actionIncomplete": false,
"parameters": {
"date": "2017-09-17",
"time": ""
},
"contexts": [],
"metadata": {
"intentId": "3dc678bb-900f-4323-9eb0-5e8342207647",
"webhookUsed": "false",
"webhookForSlotFillingUsed": "false",
"intentName": "create_task"
},
"fulfillment": {
"speech": "Сделал задачу",
"messages": [
{
"type": 0,
"speech": "Сделал задачу"
}
]
},
"score": 1
},
"status": {
"code": 200,
"errorType": "success"
},
"sessionId": "fe8a36c0-6780-435a-84bd-59d9a052e3cd"
}
Viacheslav
заранее я не знаю какой мне ответ придет, потому что он зависит от запроса
Viacheslav
поле parameters зависит от поля action
Viacheslav
как это лучше через тип выразить?
Alexander
через гадты и дата кайндс
Vladislav
"Поле A зависит от поля B" порождает два варианта:
1. симулировать зависимые типы через синглтоны (не советую, это хардкор)
2. сделать sum-тип и написать коммент про инвариант (классный и тупой Haskell98)
Alexander
ну сигнлтоны не факт что нужны
Alexander
но если будешь далеко заходить, то до них дойдет
Vladislav
Твое предложение (gadt-ы и datakinds) равносильно синглтонами
Viacheslav
но пока не понимаю как это стоит сделать