Скажем, нужно сделать функцию, на вход которой передается список по ссылке, функция его модифицирует.
Для чего это нужно?
Есть необходимо повесить на кнопку callback, который читает файл, конструирует объект и добавляет его в список объектов. Это спиок должен быть доступен в будущем и для других callback-ов. Ответ на приведенный выше вопрос интересует вне зависимости от того, какое решение проблемы будет предложено.
Здравствуйте, lse, Вы писали:
lse>Скажем, нужно сделать функцию, на вход которой передается список по ссылке, функция его модифицирует.
Data.IORef
lse>Для чего это нужно?
lse>Есть необходимо повесить на кнопку callback, который читает файл, конструирует объект и добавляет его в список объектов. Это спиок должен быть доступен в будущем и для других callback-ов. Ответ на приведенный выше вопрос интересует вне зависимости от того, какое решение проблемы будет предложено.
Не понял, чем тебе обычные списки не угодили. Ты же не думаешь, надеюсь, что в
Здравствуйте, lse, Вы писали:
lse>Скажем, нужно сделать функцию, на вход которой передается список по ссылке, функция его модифицирует.
lse>Для чего это нужно?
lse>Есть необходимо повесить на кнопку callback, который читает файл, конструирует объект и добавляет его в список объектов. Это спиок должен быть доступен в будущем и для других callback-ов. Ответ на приведенный выше вопрос интересует вне зависимости от того, какое решение проблемы будет предложено.
Предположу, что тут было бы полезно заюзать паттерн ФП Zipper, правда статья в вики несколько заморочна на мой взгляд, лучше статью Хуэта сразу смотреть — по мне там много понятней.
Здравствуйте, deniok, Вы писали:
D>Здравствуйте, lse, Вы писали:
lse>>Скажем, нужно сделать функцию, на вход которой передается список по ссылке, функция его модифицирует.
D>Data.IORef
можно пример
lse>>Для чего это нужно?
lse>>Есть необходимо повесить на кнопку callback, который читает файл, конструирует объект и добавляет его в список объектов. Это спиок должен быть доступен в будущем и для других callback-ов. Ответ на приведенный выше вопрос интересует вне зависимости от того, какое решение проблемы будет предложено.
D>Не понял, чем тебе обычные списки не угодили. Ты же не думаешь, надеюсь, что в D>
D>newList = myCoolObject : oldList
D>
D>newList в рантайме строится заново?
строится оно в рантайме заново или нет меня в этом случае не интересует, т к оно identity. Можно пример функции, на вход которой приходит список, а функция его модифицирует.
К>Предположу, что тут было бы полезно заюзать паттерн ФП Zipper, правда статья в вики несколько заморочна на мой взгляд, лучше статью Хуэта сразу смотреть — по мне там много понятней.
спасибо, буду смотреть. по первой ссылке ничего не понял, разбираюсь со второй.
Здравствуйте, lse, Вы писали:
D>>Data.IORef
lse>можно пример
do ref <- newIORef [1,2,3]
var <- readIORef ref
print var
let var = 0:var
print var
writeIORef var ref
var <- readIORef ref
print var
Если не хочется залезать в IO, тоже самое можно сделать с STRef, например.
lse>>>Для чего это нужно?
lse>строится оно в рантайме заново или нет меня в этом случае не интересует, т к оно identity. Можно пример функции, на вход которой приходит список, а функция его модифицирует.
Здравствуйте, lomeo, Вы писали:
L>Здравствуйте, lse, Вы писали:
lse>>строится оно в рантайме заново или нет меня в этом случае не интересует, т к оно identity. Можно пример функции, на вход которой приходит список, а функция его модифицирует.
L>Нет
Здравствуйте, lse, Вы писали:
D>>Data.IORef
lse>можно пример
test ss = do rs <- newIORef ss
old <- readIORef rs
writeIORef rs ('H' : tail old)
new <- readIORef rs
return (old, new)
GHCi:
*Main1> test "hello"
("hello","Hello")
lse>строится оно в рантайме заново или нет меня в этом случае не интересует, т к оно identity. Можно пример функции, на вход которой приходит список, а функция его модифицирует.
Это не идиоматично для Хаскелла. В нём нет identity. IORef в этом смысле некоторая затычка для введения ссылочной семантики в монаде IO, то есть для работы с внешними объектами. Если хочется "чистого" решения — лучше действительно зиппер использовать. Уточнил бы задачу...
Здравствуйте, deniok, Вы писали:
D>Здравствуйте, lse, Вы писали:
D>>>Data.IORef
lse>>можно пример D>
D>test ss = do rs <- newIORef ss
D> old <- readIORef rs
D> writeIORef rs ('H' : tail old)
D> new <- readIORef rs
D> return (old, new)
D>
D>GHCi: D>
D>*Main1> test "hello"
D>("hello","Hello")
D>
lse>>строится оно в рантайме заново или нет меня в этом случае не интересует, т к оно identity. Можно пример функции, на вход которой приходит список, а функция его модифицирует.
D>Это не идиоматично для Хаскелла. В нём нет identity. IORef в этом смысле некоторая затычка для введения ссылочной семантики в монаде IO, то есть для работы с внешними объектами. Если хочется "чистого" решения — лучше действительно зиппер использовать. Уточнил бы задачу...
я хотел написать, что оно не identity, опечатка. IO не подходит кажется, т к мне нужно именно модифицировать список, добавляя к нему элементы.
вот что нужно.
приблизительно так
есть кнопка, на нее:
onClick = onclick list
в onclick читается файл, преобразуется в объект-модель, затем этот объект к list добавляется ввиде элемента. list — глобальный список. все. почитал по ссылкам, zipper по описанию сюда подходит, только вот пользоваться им еще научиться надо.
Здравствуйте, lse, Вы писали:
lse>вот что нужно.
lse>приблизительно так
lse>есть кнопка, на нее: lse>onClick = onclick list
lse>в onclick читается файл, преобразуется в объект-модель, затем этот объект к list добавляется ввиде элемента. list — глобальный список. все. почитал по ссылкам, zipper по описанию сюда подходит, только вот пользоваться им еще научиться надо.
Я пока не понял, чем обычный список не подходит, и что там дальше будут за модифицирующие callback'и. Но, да, если важна эффективная модификация по месту, то зипперы рулят. Только в любом случае вызов f :: ... -> Cont a -> Cont a с точки зрения Хаскелла порождает новое значение типа Cont a. Другое дело — гарантии сложности O(1).
lse>>>строится оно в рантайме заново или нет меня в этом случае не интересует, т к оно identity. Можно пример функции, на вход которой приходит список, а функция его модифицирует.
L>>Нет
К>Дак чегож так сразу, а зиппер на что?
Ну, надо было, наверное, объяснить, что сам вопрос лишён смысла, потому что в Хаскеле нет последовательности действий, поэтому понятие "модификация" бессмысленно, если рассматривать функции как математические.
А тут и зиппер не нужен, цикл с состоянием (StateT MyState IO) в котором проверяются сигналы (скажем из входного потока) и передаются на обработчики (callback-и). Тогда callback может делать что-то вроде
myCallback :: Signal -> StateT MyState IO ()
myCallback signal = do
object <- liftIO $ getObjectFromFile (fileNameFromSignal signal)
objectList <- gets myObjects
modify $ updateObjectList (object : objectList)
Здравствуйте, lomeo, Вы писали:
L>Здравствуйте, lse, Вы писали:
D>>>Data.IORef
lse>>можно пример
L>do ref <- newIORef [1,2,3] L> var <- readIORef ref L> print var L> let var = 0:var L> print var L> writeIORef var ref L> var <- readIORef ref L> print var
отлично, могу я передать var в функцию editVar, которая меняет var, причем не возвращает его, а именно, модифицирует то, что есть, чтобы потом изменения наружу торчали?
Здравствуйте, lomeo, Вы писали:
lse>>>>строится оно в рантайме заново или нет меня в этом случае не интересует, т к оно identity. Можно пример функции, на вход которой приходит список, а функция его модифицирует.
L>>>Нет
К>>Дак чегож так сразу, а зиппер на что?
L>Ну, надо было, наверное, объяснить, что сам вопрос лишён смысла, потому что в Хаскеле нет последовательности действий, поэтому понятие "модификация" бессмысленно, если рассматривать функции как математические.
L>А тут и зиппер не нужен, цикл с состоянием (StateT MyState IO) в котором проверяются сигналы (скажем из входного потока) и передаются на обработчики (callback-и). Тогда callback может делать что-то вроде
L>
Знаешь, всё это терминологический спор, т.е. по сути изоморфные вещи, если погрубей — "те же яйца, только сбоку".
Реально пусть товарищ попробует то, что ему будет понятней и по скоросте внятней.
Здравствуйте, lse, Вы писали:
lse>отлично, могу я передать var в функцию editVar, которая меняет var, причем не возвращает его, а именно, модифицирует то, что есть, чтобы потом изменения наружу торчали?
Нет.
В Haskell-е нет переменных, там только значения — поэтому там ничего нельзя "модифицировать". Чтобы была глобальная область видимости и изменяемость, воспользуйся ссылками.
Для того, чтобы понять это, попробуй сам написать реализацию ссылок на чистом Хаскеле, возьми за основу монаду состояния, тогда ты поймёшь о чём идёт речь.
Посмотри на это по другому — а зачем тебе менять именно var, а не ref, или выбрать вообще другой путь?
Здравствуйте, Курилка, Вы писали:
К>Знаешь, всё это терминологический спор, т.е. по сути изоморфные вещи, если погрубей — "те же яйца, только сбоку".
С другой стороны этот спор изоморфен приятной дружеской беседе, в которой мы в меру своих сил пытаемся помочь коллеге, показывая разные взгляду на одну проблему
К>Реально пусть товарищ попробует то, что ему будет понятней и по скоросте внятней.
+1.
Хорошо было бы на саму задачу посмотреть, чтобы показать пути решения, а то у lse императивные представления (модификация).
Здравствуйте, lomeo, Вы писали:
L>Ну, надо было, наверное, объяснить, что сам вопрос лишён смысла, потому что в Хаскеле нет последовательности действий, поэтому понятие "модификация" бессмысленно, если рассматривать функции как математические.
Я знаю, что в чистых функциях все именно так.
L>А тут и зиппер не нужен, цикл с состоянием (StateT MyState IO) в котором проверяются сигналы (скажем из входного потока) и передаются на обработчики (callback-и). Тогда callback может делать что-то вроде
L>
object <- liftIO $ .... — это что такое? что за liftIO?
Откровенно говоря, все, что мне нужно — это схематчески набросанный пример с окном, на котором кнопка, при нажатии на кнопку к глобальной коллекции происходит добавление нового числа. Один раз нажали — [1], второй раз нажали — [1,2], третий раз — [1,2,3].
а как на счет этого?
main = do
rs <- newIORef [1,2,3]
test rs
test rs = do
oldRs <- readIORef rs
writeIORef rs ('1' : oldRs)
return rs
lse>Откровенно говоря, все, что мне нужно — это схематчески набросанный пример с окном, на котором кнопка, при нажатии на кнопку к глобальной коллекции происходит добавление нового числа. Один раз нажали — [1], второй раз нажали — [1,2], третий раз — [1,2,3].
Ну и напиши модификатор
modList lst@(x:xs) = (x+1):lst
(Добавляют обычно в голову, если обязательно в хвост — добавь reverse, например.)
И дёргай его при каждом нажатии.
А глобальной коллекции не бывает — старую передаёшь, новую получаешь. Нет объектов с identity