haskell, изменяемое состояние
От: lse  
Дата: 22.01.08 11:18
Оценка:
Скажем, нужно сделать функцию, на вход которой передается список по ссылке, функция его модифицирует.

Для чего это нужно?

Есть необходимо повесить на кнопку callback, который читает файл, конструирует объект и добавляет его в список объектов. Это спиок должен быть доступен в будущем и для других callback-ов. Ответ на приведенный выше вопрос интересует вне зависимости от того, какое решение проблемы будет предложено.
Re: haskell, изменяемое состояние
От: deniok Россия  
Дата: 22.01.08 11:32
Оценка:
Здравствуйте, lse, Вы писали:

lse>Скажем, нужно сделать функцию, на вход которой передается список по ссылке, функция его модифицирует.


Data.IORef

lse>Для чего это нужно?


lse>Есть необходимо повесить на кнопку callback, который читает файл, конструирует объект и добавляет его в список объектов. Это спиок должен быть доступен в будущем и для других callback-ов. Ответ на приведенный выше вопрос интересует вне зависимости от того, какое решение проблемы будет предложено.


Не понял, чем тебе обычные списки не угодили. Ты же не думаешь, надеюсь, что в
newList = myCoolObject : oldList

newList в рантайме строится заново?
Re: haskell, изменяемое состояние
От: Курилка Россия http://kirya.narod.ru/
Дата: 22.01.08 11:33
Оценка: 2 (1)
Здравствуйте, lse, Вы писали:

lse>Скажем, нужно сделать функцию, на вход которой передается список по ссылке, функция его модифицирует.


lse>Для чего это нужно?


lse>Есть необходимо повесить на кнопку callback, который читает файл, конструирует объект и добавляет его в список объектов. Это спиок должен быть доступен в будущем и для других callback-ов. Ответ на приведенный выше вопрос интересует вне зависимости от того, какое решение проблемы будет предложено.


Предположу, что тут было бы полезно заюзать паттерн ФП Zipper, правда статья в вики несколько заморочна на мой взгляд, лучше статью Хуэта сразу смотреть — по мне там много понятней.
Re[2]: haskell, изменяемое состояние
От: lse  
Дата: 22.01.08 11:54
Оценка:
Здравствуйте, deniok, Вы писали:

D>Здравствуйте, lse, Вы писали:


lse>>Скажем, нужно сделать функцию, на вход которой передается список по ссылке, функция его модифицирует.


D>Data.IORef


можно пример

lse>>Для чего это нужно?


lse>>Есть необходимо повесить на кнопку callback, который читает файл, конструирует объект и добавляет его в список объектов. Это спиок должен быть доступен в будущем и для других callback-ов. Ответ на приведенный выше вопрос интересует вне зависимости от того, какое решение проблемы будет предложено.


D>Не понял, чем тебе обычные списки не угодили. Ты же не думаешь, надеюсь, что в

D>
D>newList = myCoolObject : oldList
D>

D>newList в рантайме строится заново?

строится оно в рантайме заново или нет меня в этом случае не интересует, т к оно identity. Можно пример функции, на вход которой приходит список, а функция его модифицирует.
Re[2]: haskell, изменяемое состояние
От: lse  
Дата: 22.01.08 11:55
Оценка:
К>Предположу, что тут было бы полезно заюзать паттерн ФП Zipper, правда статья в вики несколько заморочна на мой взгляд, лучше статью Хуэта сразу смотреть — по мне там много понятней.

спасибо, буду смотреть. по первой ссылке ничего не понял, разбираюсь со второй.
Re[3]: haskell, изменяемое состояние
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 22.01.08 12:23
Оценка:
Здравствуйте, 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. Можно пример функции, на вход которой приходит список, а функция его модифицирует.


Нет
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[4]: haskell, изменяемое состояние
От: Курилка Россия http://kirya.narod.ru/
Дата: 22.01.08 12:28
Оценка:
Здравствуйте, lomeo, Вы писали:

L>Здравствуйте, lse, Вы писали:


lse>>строится оно в рантайме заново или нет меня в этом случае не интересует, т к оно identity. Можно пример функции, на вход которой приходит список, а функция его модифицирует.


L>Нет


Дак чегож так сразу, а зиппер на что?
Re[3]: haskell, изменяемое состояние
От: deniok Россия  
Дата: 22.01.08 12:32
Оценка:
Здравствуйте, 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, то есть для работы с внешними объектами. Если хочется "чистого" решения — лучше действительно зиппер использовать. Уточнил бы задачу...
Re[4]: haskell, изменяемое состояние
От: lse  
Дата: 22.01.08 12:41
Оценка:
Здравствуйте, 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 по описанию сюда подходит, только вот пользоваться им еще научиться надо.
Re[5]: haskell, изменяемое состояние
От: deniok Россия  
Дата: 22.01.08 12:51
Оценка:
Здравствуйте, lse, Вы писали:

lse>вот что нужно.


lse>приблизительно так


lse>есть кнопка, на нее:

lse>onClick = onclick list

lse>в onclick читается файл, преобразуется в объект-модель, затем этот объект к list добавляется ввиде элемента. list — глобальный список. все. почитал по ссылкам, zipper по описанию сюда подходит, только вот пользоваться им еще научиться надо.


Я пока не понял, чем обычный список не подходит, и что там дальше будут за модифицирующие callback'и. Но, да, если важна эффективная модификация по месту, то зипперы рулят. Только в любом случае вызов f :: ... -> Cont a -> Cont a с точки зрения Хаскелла порождает новое значение типа Cont a. Другое дело — гарантии сложности O(1).
Re[4]: haskell, изменяемое состояние
От: lse  
Дата: 22.01.08 12:54
Оценка:
Здравствуйте, 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>



а пример не катит. нужно не измененный список возвращать, а именно модифицировать переданный по ссылке.
Re[5]: haskell, изменяемое состояние
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 22.01.08 12:55
Оценка:
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)
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[4]: haskell, изменяемое состояние
От: lse  
Дата: 22.01.08 12:59
Оценка:
Здравствуйте, 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, причем не возвращает его, а именно, модифицирует то, что есть, чтобы потом изменения наружу торчали?
Re[6]: haskell, изменяемое состояние
От: Курилка Россия http://kirya.narod.ru/
Дата: 22.01.08 13:08
Оценка: +1
Здравствуйте, lomeo, Вы писали:

lse>>>>строится оно в рантайме заново или нет меня в этом случае не интересует, т к оно identity. Можно пример функции, на вход которой приходит список, а функция его модифицирует.


L>>>Нет


К>>Дак чегож так сразу, а зиппер на что?


L>Ну, надо было, наверное, объяснить, что сам вопрос лишён смысла, потому что в Хаскеле нет последовательности действий, поэтому понятие "модификация" бессмысленно, если рассматривать функции как математические.


L>А тут и зиппер не нужен, цикл с состоянием (StateT MyState IO) в котором проверяются сигналы (скажем из входного потока) и передаются на обработчики (callback-и). Тогда callback может делать что-то вроде


L>
L>myCallback :: Signal -> StateT MyState IO ()
L>myCallback signal = do
L>    object <- liftIO $ getObjectFromFile (fileNameFromSignal signal)
L>        objectList <- gets myObjects
L>        modify $ updateObjectList (object : objectList)
L>


Знаешь, всё это терминологический спор, т.е. по сути изоморфные вещи, если погрубей — "те же яйца, только сбоку".
Реально пусть товарищ попробует то, что ему будет понятней и по скоросте внятней.
Re[5]: haskell, изменяемое состояние
От: deniok Россия  
Дата: 22.01.08 13:09
Оценка:
Здравствуйте, lse, Вы писали:

lse>а пример не катит. нужно не измененный список возвращать, а именно модифицировать переданный по ссылке.


old и new я ввёл, чтобы продемонстрировать, что rs — мутирует внутри IO. По сути достаточно было
test ss = do rs <- newIORef ss
             modifyIORef rs (\xs -> 'H' : tail xs)
             readIORef rs

Я же не напрямую твою задачу решаю, а демонстрирую как создавать модифицируемую ссылку на список.
Re[5]: haskell, изменяемое состояние
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 22.01.08 13:22
Оценка:
Здравствуйте, lse, Вы писали:

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


Нет.

В Haskell-е нет переменных, там только значения — поэтому там ничего нельзя "модифицировать". Чтобы была глобальная область видимости и изменяемость, воспользуйся ссылками.

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

Посмотри на это по другому — а зачем тебе менять именно var, а не ref, или выбрать вообще другой путь?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[7]: haskell, изменяемое состояние
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 22.01.08 13:22
Оценка: 1 (1)
Здравствуйте, Курилка, Вы писали:

К>Знаешь, всё это терминологический спор, т.е. по сути изоморфные вещи, если погрубей — "те же яйца, только сбоку".


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

К>Реально пусть товарищ попробует то, что ему будет понятней и по скоросте внятней.


+1.

Хорошо было бы на саму задачу посмотреть, чтобы показать пути решения, а то у lse императивные представления (модификация).
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[6]: haskell, изменяемое состояние
От: lse  
Дата: 22.01.08 13:37
Оценка:
Здравствуйте, lomeo, Вы писали:

L>Ну, надо было, наверное, объяснить, что сам вопрос лишён смысла, потому что в Хаскеле нет последовательности действий, поэтому понятие "модификация" бессмысленно, если рассматривать функции как математические.


Я знаю, что в чистых функциях все именно так.

L>А тут и зиппер не нужен, цикл с состоянием (StateT MyState IO) в котором проверяются сигналы (скажем из входного потока) и передаются на обработчики (callback-и). Тогда callback может делать что-то вроде


L>
L>myCallback :: Signal -> StateT MyState IO ()
L>myCallback signal = do
L>    object <- liftIO $ getObjectFromFile (fileNameFromSignal signal)
L>        objectList <- gets myObjects
L>        modify $ updateObjectList (object : objectList)
L>


Если конкретнее — то это wxHaskell.

Нужны пояснения.

getObjectFromFile (fileNameFromSignal signal) — возвращает объект, соотв. файлу

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
Re[7]: haskell, изменяемое состояние
От: lse  
Дата: 22.01.08 13:44
Оценка:
lse>
lse>main = do
lse>    rs <- newIORef [1,2,3]
lse>    test rs

lse>test rs = do
lse>oldRs <- readIORef rs
lse>writeIORef rs ('1' : oldRs)
lse>return rs
lse>


ошибка — вот так:

main = do
rs <- newIORef [1,2,3]
test rs

test rs = do
oldRs <- readIORef rs
writeIORef rs ('1' : oldRs)
return


по идее ведь rs должен изменитьсяи в main?
Re[7]: haskell, изменяемое состояние
От: deniok Россия  
Дата: 22.01.08 13:46
Оценка:
Здравствуйте, lse, Вы писали:


lse>Откровенно говоря, все, что мне нужно — это схематчески набросанный пример с окном, на котором кнопка, при нажатии на кнопку к глобальной коллекции происходит добавление нового числа. Один раз нажали — [1], второй раз нажали — [1,2], третий раз — [1,2,3].


Ну и напиши модификатор
modList lst@(x:xs) = (x+1):lst

(Добавляют обычно в голову, если обязательно в хвост — добавь reverse, например.)
И дёргай его при каждом нажатии.

А глобальной коллекции не бывает — старую передаёшь, новую получаешь. Нет объектов с identity
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.