Re[8]: haskell, изменяемое состояние
От: lse  
Дата: 22.01.08 14:04
Оценка:
Здравствуйте, 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-ов?
Re[7]: haskell, изменяемое состояние
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 22.01.08 14:18
Оценка: 2 (1)
Здравствуйте, lse, Вы писали:

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


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


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


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>>


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 тебе давали
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[9]: haskell, изменяемое состояние
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 22.01.08 14:18
Оценка:
Здравствуйте, lse, Вы писали:

lse>Как тогда хранить list между вызовами callback-ов?


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

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


lse>>Как тогда хранить list между вызовами callback-ов?


L>Хранить надо ссылку. Её то можно модифицировать (менять значение, на которое оно ссылается).


Ну а я о чем говорю уже 2 часа? Это-то и нужно было. Ссылка на объект — самое то. А тут говорят — ссылки запрещены.

Спасибо.
Re[9]: haskell, изменяемое состояние
От: deniok Россия  
Дата: 22.01.08 14:48
Оценка: 2 (1)
Здравствуйте, lse, Вы писали:



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).

отсюда

Поэтому в WxHaskell это делается по-императивному: там для этого есть
type Var a = IORef a

здесь

Посмотри также Graphics.UI.WX.Variable, возможно это будет несколько удобнее.

Пример использования Var — игра Bouncing balls отсюда.

А более "функциональные" решения для state management сделано в надстройке над WxHaskell, wxFruit.
Re[11]: haskell, изменяемое состояние
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 22.01.08 14:56
Оценка:
Здравствуйте, lse, Вы писали:

lse>Ну а я о чем говорю уже 2 часа? Это-то и нужно было. Ссылка на объект — самое то. А тут говорят — ссылки запрещены.


Ты невнимательно читаешь — тебе говорили про ссылки с первых постов, запрещены модификации.

lse>Спасибо.


Рад, что смог помочь.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[3]: haskell, изменяемое состояние
От: geniepro http://geniepro.livejournal.com/
Дата: 22.01.08 17:39
Оценка:
Здравствуйте, lse, Вы писали:

lse> Можно пример функции, на вход которой приходит список, а функция его модифицирует?


Ежели это список ссылок на мутабельные переменные (напр. IORef), то вот:
{- Алгоритм на псевдокоде примерно такой:

void sort (Ord el => el arr[])
{
    int len = length (arr);

    for (int i = 1; i < len; i++)
    {
        for (int j = 0; j < i; j++)
        {
            if (arr [j] > arr [i])
            {
                (arr [i], arr [j]) = (arr [j], arr [i]);
            }
        }
    }
}

-}

import Data.IORef
import Control.Monad

sort arr = do
    let len = length arr
    forM [1..len-1] $ \i -> do
        forM [0..i-1] $ \j -> do
            arr'i <- arr !!! i
            arr'j <- arr !!! j
            when (arr'j > arr'i) $ do
                 (arr !! i) =:= arr'j
                 (arr !! j) =:= arr'i

main = do
    array <- toIORefs [ 10, 9..1 ]

    putStr   "Unsorted array: "
    printArr array

    sort     array

    putStr   "Sorted array:   "
    printArr array


arr !!! n = readIORef $ arr !! n
ref =:= n = writeIORef ref n

fromIORefs   = mapM readIORef
toIORefs     = mapM newIORef
printArr arr = fromIORefs arr >>= print
Результат:
Unsorted array: [10,9,8,7,6,5,4,3,2,1]
Sorted array:   [1,2,3,4,5,6,7,8,9,10]
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.