Форум программистов, компьютерный форум, киберфорум
Haskell
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/4: Рейтинг темы: голосов - 4, средняя оценка - 5.00
 Аватар для Araneo
650 / 260 / 16
Регистрация: 02.03.2014
Сообщений: 587

Моя реализация акторной модели

29.09.2015, 13:32. Показов 755. Ответов 2
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Моя реализация акторной модели в рамках Хаскеля.
Кликните здесь для просмотра всего текста
Haskell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
{-# Language
    GADTs,
    LambdaCase,
    FlexibleInstances,
    MultiParamTypeClasses#-}
 
module Actor where
 
import Control.Monad
import Control.Monad.Fix
import Control.Monad.Free
import Control.Concurrent
import Control.Concurrent.Chan
import qualified System.Random as R
 
type Process = Free Interaction
 
data Interaction next where
    ReadMsg     ::               Chan a -> (a -> next) -> Interaction next
    WriteMsg    ::               Chan a ->  a -> next  -> Interaction next
    MakeChan    ::                    (Chan a -> next) -> Interaction next
    Random      :: R.Random a => a -> a -> (a -> next) -> Interaction next
    ForkProcess ::               Process ()   -> next  -> Interaction next
 
instance Functor Interaction where
    fmap f = \case 
        ReadMsg  chan   g -> ReadMsg  chan   $ f.g
        WriteMsg chan a g -> WriteMsg chan a $ f g
        MakeChan        g -> MakeChan        $ f.g
        Random    a b   g -> Random    a b   $ f.g 
        ForkProcess p   g -> ForkProcess p   $ f g
 
class Monad m => Eval m where
    eval     :: Process ()  -> m()
    forkEval :: Process ()  -> m()
    writeMsg :: Chan a -> a -> m()
    readMsg  :: Chan a      -> m a
    makeChan :: m (Chan a)
 
instance Eval IO where
    eval = \case
        Free r                -> case r of
            ReadMsg  chan   f -> eval =<< f <$> readChan chan
            MakeChan        f -> eval =<< f <$> newChan
            WriteMsg chan a f -> writeChan chan a *> eval f
            Random      a b f -> eval =<< f <$> R.randomRIO (a, b)
            ForkProcess   p f -> forkIO (eval p)  *> eval f 
        Pure r                -> return r
 
    forkEval = void.forkIO.eval
    writeMsg = writeChan
    readMsg  = readChan
    makeChan = newChan
 
instance Eval Process where
    eval f          = lift $ ForkProcess f ()
    writeMsg chan a = lift $ WriteMsg chan a ()
    readMsg  chan   = lift $ ReadMsg  chan id
    makeChan        = lift $ MakeChan      id
    forkEval        = eval
 
random a b = lift $ Random a b id
 
lift x = Free (fmap Pure x)
 
class Actor a b where
    aktor  :: a -> b
 
type Handler msg b = Chan msg -> Free Interaction b
type Result m1 m2 msg  = m1 (msg -> m2 ())
 
instance (Eval m1, Eval m2) => Actor (Handler msg b) (Result m1 m2 msg) where
    aktor f = do
        ch <- makeChan
        forkEval.void   $ f ch
        return.writeMsg $   ch
 
instance (Eval m1, Eval m2) =>
    Actor (Handler msg b -> Handler msg b) (Result m1 m2 msg) where
    aktor f = aktor.fix $ f
 
aktorST s f = aktor  $ fix f s
forkST  s f = forkIO $ fix f s

И небольшая программка с её использованием.
Кликните здесь для просмотра всего текста
Haskell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
{-# Language MultiWayIf, LambdaCase#-}
-- ghc Main.hs -O2 -threaded
module Main where
 
import Control.Monad
import Control.Concurrent
import Control.Concurrent.Thread.Delay
import System.IO
import System.Console.ANSI
import Actor
 
widths = 22
height = 78
 
metronome t f = forkIO.forever $ delay t >> f
 
data Point = Point Int Int deriving Eq
 
data PointRequest = Up | Down | Forward | Backward | Jamp | Draw
 
point :: Point -> Chan Point -> Chan PointRequest -> Process ()
point p@(Point x y) out ch = readMsg ch >>= \case
    Up       | y > 1      -> point' $ Point x    (y-1)
    Down     | y < widths -> point' $ Point x    (y+1)
    Forward  | x < height -> point' $ Point (x+1) y
    Backward | x > 1      -> point' $ Point (x-1) y
    Draw                  -> writeMsg out p >> point' p
    Jamp                  -> do
        y <- random 1 widths
        x <- random 1 height
        point' $ Point x y
    _                     -> point' p
  where point' p = point p out ch
 
background = concat $ do
    n <- [0..widths + 1]
    return $ if
        | n == 0          -> '+':replicate height '-' ++ "+\n"
        | n == widths + 1 -> '+':replicate height '-' ++ "+"
        | otherwise       -> '|':replicate height ' ' ++ "|\n"
 
getKey :: (PointRequest -> IO ()) -> IO ()
getKey command = getChar >>= \case
    'w' -> command Up       *> next
    's' -> command Down     *> next
    'd' -> command Forward  *> next
    'a' -> command Backward *> next
    'j' -> command Jamp     *> next
    '!' ->                     exit
    _   ->                     next
  where next = getKey command
 
exit = do
    clearScreen
    setCursorPosition 0 0
    showCursor
 
printer p@(Point x y) chan = do
    p'@(Point x' y') <- readChan chan
    when (p /= p') $ do
        setCursorPosition y  x  *> putStr " "
        setCursorPosition y' x' *> putStr "X" 
    printer p' chan
 
main = do
    hSetBuffering stdin  NoBuffering
    hSetBuffering stdout NoBuffering
    hSetEcho stdin False
    hideCursor
 
    chan  <- makeChan
    forkIO $ do
        putStr background 
        printer (Point 3 4) chan
    point <- aktor $ point (Point 3 5) chan
    metronome 10000 $ point Draw
    getKey point

Вопрос. Насколько аккуратно выглядит код?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
29.09.2015, 13:32
Ответы с готовыми решениями:

Баг или моя ошибка в передаче модели
Привет ребят.И вновь вопрос с передачей нужной модели. Нужен совет профи. Есть модель комментов, создана CommentsViewModel Public Class...

Ваша идея, моя реализация
Хочется попрактиковаться в написании программ с использованием wxWidgets. Если проще - речь идет о написании кроссплатформенных...

Моя реализация функции перевода string в int
#include &lt;iostream&gt; #include &lt;string&gt; using namespace std; int str_to_int(string a); int main() { string s =...

2
Супер-модератор
Эксперт функциональных языков программированияЭксперт Python
 Аватар для Catstail
38194 / 21127 / 4309
Регистрация: 12.02.2012
Сообщений: 34,733
Записей в блоге: 14
29.09.2015, 16:58
С моей точки зрения, код оформлен очень хорошо.
0
Антикодер
Эксперт функциональных языков программирования
1888 / 870 / 48
Регистрация: 15.09.2012
Сообщений: 3,088
30.09.2015, 11:58
могу только посоветовать добавить разрешение на экспорт только необходимых функций из модуля.
2
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
30.09.2015, 11:58
Помогаю со студенческими работами здесь

Моя реализация функции перевода STRING в DOUBLE
#include &lt;iostream&gt; #include &lt;string&gt; using namespace std; double str_to_double(string a); int main() { string s =...

Реализация дэка. Подскажите,в чем моя ошибка?
Задание такое: Дек организован в массиве с циклическим заполнением и с использованием двунаправленного списка. Операции выполняются с...

Функция задержки в stm8 iar - моя реализация delay_us
Когда я начинал програмить на stm8 в среде iar, мне жутко не хватало задержек по типу привычных _delay_us на авр. поэтому я написал свою...

Python unpack('i') питоновская анпак integer моя реализация
Предыстория с задачей: Возникла задача разобрать на C# бинарный файл с данными. недолго думая &quot;великий&quot; гуглопоиск выдал ссылку...

Моя реализация алгоритма перевода числа в пропись (русский язык)
Добрый день.Недавно передо мной стояла задача сделать REST сервис перевода числа в пропись(на русском языке).Я хочу,чтобы мой код...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Новые блоги и статьи
Кому нужен AOT?
DevAlt 26.03.2026
Решил сделать простой ланчер Написал заготовку: dotnet new console --aot -o UrlHandler var items = args. Split(":"); var tag = items; var id = items; var executable = args;. . .
Отправка уведомления на почту при изменении наименования справочника
Maks 24.03.2026
Программная отправка письма электронной почты на примере изменения наименования типового справочника "Склады" в конфигурации БП3. Перед реализацией необходимо выполнить настройку системной учетной. . .
модель ЗдравоСохранения 5. Меньше увольнений- больше дохода!
anaschu 24.03.2026
Теперь система здравосохранения уменьшает количество увольнений. 9TO2GP2bpX4 a42b81fb172ffc12ca589c7898261ccb/ https:/ / rutube. ru/ video/ a42b81fb172ffc12ca589c7898261ccb/ Слева синяя линия -. . .
Midnight Chicago Blues
kumehtar 24.03.2026
Такой Midnight Chicago Blues, знаешь?. . Когда вечерние улицы становятся ночными, а ты не можешь уснуть. Ты идёшь в любимый старый бар, и бармен наливает тебе виски. Ты смотришь на пролетающие. . .
SDL3 для Desktop (MinGW): Вывод текста со шрифтом TTF с помощью библиотеки SDL3_ttf на Си и C++
8Observer8 24.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-text-sdl3-c. zip finish-text-sdl3-cpp. zip
Жизнь в неопределённости
kumehtar 23.03.2026
Жизнь — это постоянное существование в неопределённости. Например, даже если у тебя есть список дел, невозможно дойти до точки, где всё окончательно завершено и больше ничего не осталось. В принципе,. . .
Модель здравоСохранения: работники работают быстрее после её введения.
anaschu 23.03.2026
geJalZw1fLo Корпорация до введения программа здравоохранения имела много невыполненных работниками заданий, после введения программы количество заданий выросло. Но на выплатах по больничным это. . .
Контроль уникальности заводского номера
Maks 23.03.2026
Алгоритм контроля уникальности заводского (или серийного) номера на примере нетипового документа выдачи шин для спецтехники с табличной частью, разработанного в конфигурации КА2. Номеклатура. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru