2013-08-01 8 views
4

Скажем, у меня есть процесс, который модифицирует основное состояние, которое является Int:Использование Data.Machine, как вы можете создать два ProcessT вместе, которые изменяют два разных состояния?

p1 :: ProcessT (State Int) Int Int 
p1 = repeatedly $ do 
    a <- await 
    lift . modify $ (+a) 
    yield a 

И еще, что модифицирует основное состояние, которое является [Int]:

p2 :: ProcessT (State [Int]) Int Bool 
p2 = repeatedly $ do 
    a <- await 
    lift . modify $ (++[a]) 
    as <- get 
    if length as > 3 then yield True else yield False 

Я хочу, чтобы составить им это путь:

p3 = source [1...6] ~> p1 ~ p2 

и запустить их, как:

flip runState 0 . flip runState [] . runT $ p3 

Но я получаю эту ошибку:

Couldn't match expected type `Int' with actual type `[Int]' 
    Expected type: ProcessT (State Int) Int c0 
    Actual type: ProcessT (State [Int]) Int Bool 
    In the second argument of `(~>)', namely `p2' 
    In the expression: source [1 .. 6] ~> p1 ~> p2 

Советовать p1 и p2 должны иметь один и тот же тип основного состояния. Фактически, небольшой эксперимент показывает, что p1 и p2 фактически модифицируют базовое состояние . Как я могу обойти это?

ответ

3

Вы можете сделать большее состояние и изменить каждое вычисление, чтобы взять объектив в большее составное состояние системы.

p1 :: (MonadState s m, Num a) => Lens' s a -> ProcessT m a a 
p1 l = repeatedly $ do 
    a <- await 
    l += a 
    yield a 

Вам тогда просто нужно поставить большее составное состояние и соответствующие линзы, чтобы управлять всем.

+2

Вы также можете предоставить функцию «mapProcessT», чтобы люди могли легко поднять масштаб. –

+0

Я был бы рад добавить патч, добавив его. ;) –

+0

На самом деле, теперь, когда я думаю об этом, я думаю, что он уже там, как 'fit'. –

 Смежные вопросы

  • Нет связанных вопросов^_^