Здравствуйте, lse, Вы писали:
lse>Скажем, нужно сделать функцию, на вход которой передается список по ссылке, функция его модифицирует.
lse>Для чего это нужно?
lse>Есть необходимо повесить на кнопку callback, который читает файл, конструирует объект и добавляет его в список объектов. Это спиок должен быть доступен в будущем и для других callback-ов. Ответ на приведенный выше вопрос интересует вне зависимости от того, какое решение проблемы будет предложено.
Предположу, что тут было бы полезно заюзать паттерн ФП Zipper, правда статья в вики несколько заморочна на мой взгляд, лучше статью Хуэта сразу смотреть — по мне там много понятней.
Здравствуйте, lse, Вы писали:
lse>Здравствуйте, lomeo, Вы писали:
L>>Ну, надо было, наверное, объяснить, что сам вопрос лишён смысла, потому что в Хаскеле нет последовательности действий, поэтому понятие "модификация" бессмысленно, если рассматривать функции как математические.
lse>Я знаю, что в чистых функциях все именно так.
L>>А тут и зиппер не нужен, цикл с состоянием (StateT MyState IO) в котором проверяются сигналы (скажем из входного потока) и передаются на обработчики (callback-и). Тогда callback может делать что-то вроде
L>>
lse>Если конкретнее — то это wxHaskell.
lse>Нужны пояснения.
lse>getObjectFromFile (fileNameFromSignal signal) — возвращает объект, соотв. файлу
lse>object <- liftIO $ .... — это что такое? что за liftIO?
Мы работает в StateT MyState IO, потому что нам надо работать с IO (работа с файлом). Для того, чтобы позвать обёрнутый трансформером IO делают liftIO. В данном случае он имеет тип IO Object -> StateT MyState IO Object, т.к. getObjectFromFile (fileNameFromSignal signal) :: IO Object.
lse>Откровенно говоря, все, что мне нужно — это схематчески набросанный пример с окном, на котором кнопка, при нажатии на кнопку к глобальной коллекции происходит добавление нового числа. Один раз нажали — [1], второй раз нажали — [1,2], третий раз — [1,2,3].
Что то вроде
do ref <- newIORef []
f <- frame [text := "lse test"]
incBtn <- button f [text := "Inc", on command := modifyIORef ref updateMyList]
printBtn <- button f [text := "Print", on command := (readIORef >>= print . reverse)]
where
updateMyList xs = (length xs) : xs
lse>а как на счет этого?
Замечательно, это именно то, что я и deniok тебе давали
lse>Как тогда хранить list между вызовами callback-ов? lse>Я знаю, что нет identity. Но не предсталвяю, как вот в этом случае можно обойтись без модификации.
В WxHaskell действительно никак.
Unlike more functional GUI libraries, wxHaskell does not provide a model for state management and uses simple mutable variables to communicate state across different event handlers. (Note: this is a concious design decision – as functional GUI interfaces are still very much a research area, we want to provide a full fledged GUI library using simple IO first, than try to build good functional interfaces on top of that).
Здравствуйте, Курилка, Вы писали:
К>Знаешь, всё это терминологический спор, т.е. по сути изоморфные вещи, если погрубей — "те же яйца, только сбоку".
С другой стороны этот спор изоморфен приятной дружеской беседе, в которой мы в меру своих сил пытаемся помочь коллеге, показывая разные взгляду на одну проблему
К>Реально пусть товарищ попробует то, что ему будет понятней и по скоросте внятней.
+1.
Хорошо было бы на саму задачу посмотреть, чтобы показать пути решения, а то у lse императивные представления (модификация).
Здравствуйте, lomeo, Вы писали:
lse>>>>строится оно в рантайме заново или нет меня в этом случае не интересует, т к оно identity. Можно пример функции, на вход которой приходит список, а функция его модифицирует.
L>>>Нет
К>>Дак чегож так сразу, а зиппер на что?
L>Ну, надо было, наверное, объяснить, что сам вопрос лишён смысла, потому что в Хаскеле нет последовательности действий, поэтому понятие "модификация" бессмысленно, если рассматривать функции как математические.
L>А тут и зиппер не нужен, цикл с состоянием (StateT MyState IO) в котором проверяются сигналы (скажем из входного потока) и передаются на обработчики (callback-и). Тогда callback может делать что-то вроде
L>
Знаешь, всё это терминологический спор, т.е. по сути изоморфные вещи, если погрубей — "те же яйца, только сбоку".
Реально пусть товарищ попробует то, что ему будет понятней и по скоросте внятней.
Скажем, нужно сделать функцию, на вход которой передается список по ссылке, функция его модифицирует.
Для чего это нужно?
Есть необходимо повесить на кнопку callback, который читает файл, конструирует объект и добавляет его в список объектов. Это спиок должен быть доступен в будущем и для других callback-ов. Ответ на приведенный выше вопрос интересует вне зависимости от того, какое решение проблемы будет предложено.
Здравствуйте, lse, Вы писали:
lse>Скажем, нужно сделать функцию, на вход которой передается список по ссылке, функция его модифицирует.
Data.IORef
lse>Для чего это нужно?
lse>Есть необходимо повесить на кнопку callback, который читает файл, конструирует объект и добавляет его в список объектов. Это спиок должен быть доступен в будущем и для других callback-ов. Ответ на приведенный выше вопрос интересует вне зависимости от того, какое решение проблемы будет предложено.
Не понял, чем тебе обычные списки не угодили. Ты же не думаешь, надеюсь, что в
Здравствуйте, 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, причем не возвращает его, а именно, модифицирует то, что есть, чтобы потом изменения наружу торчали?
Здравствуйте, lse, Вы писали:
lse>отлично, могу я передать var в функцию editVar, которая меняет var, причем не возвращает его, а именно, модифицирует то, что есть, чтобы потом изменения наружу торчали?
Нет.
В Haskell-е нет переменных, там только значения — поэтому там ничего нельзя "модифицировать". Чтобы была глобальная область видимости и изменяемость, воспользуйся ссылками.
Для того, чтобы понять это, попробуй сам написать реализацию ссылок на чистом Хаскеле, возьми за основу монаду состояния, тогда ты поймёшь о чём идёт речь.
Посмотри на это по другому — а зачем тебе менять именно var, а не ref, или выбрать вообще другой путь?
Здравствуйте, 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
Здравствуйте, deniok, Вы писали:
D>Здравствуйте, lse, Вы писали:
lse>>Откровенно говоря, все, что мне нужно — это схематчески набросанный пример с окном, на котором кнопка, при нажатии на кнопку к глобальной коллекции происходит добавление нового числа. Один раз нажали — [1], второй раз нажали — [1,2], третий раз — [1,2,3].
D>Ну и напиши модификатор D>
D>modList lst@(x:xs) = (x+1):lst
D>
D>(Добавляют обычно в голову, если обязательно в хвост — добавь reverse, например.) D>И дёргай его при каждом нажатии.
D>А глобальной коллекции не бывает — старую передаёшь, новую получаешь. Нет объектов с identity
Как тогда хранить list между вызовами callback-ов?
Я знаю, что нет identity. Но не предсталвяю, как вот в этом случае можно обойтись без модификации.
псевдоязык, инициализация главного окна
initWindow =
Window window
List list
window.onClick=onclick list
как функция obclick "будет возвращать модифицированный объект"? если ты скажешь, я буду очень удивлен. тут единственный вариант — дать на вход ей ссылку на mutable-список. Как хранить list между вызовами callback-ов?
Здравствуйте, lomeo, Вы писали:
L>Здравствуйте, lse, Вы писали:
lse>>Как тогда хранить list между вызовами callback-ов?
L>Хранить надо ссылку. Её то можно модифицировать (менять значение, на которое оно ссылается).
Ну а я о чем говорю уже 2 часа? Это-то и нужно было. Ссылка на объект — самое то. А тут говорят — ссылки запрещены.