2013-04-18 2 views
1

Я застрял пытается получить эту функцию:Haskell- Запуск монады состояния

runArrayState :: Array arr => ArrayState arr e a -> arr e -> (a, arr e) 

запустить действие ArrayState давайте назовем его акт с массивом обр и получить результат и вернуть результат Рез и исходный массив arr ' как пара (res, arr').

ArrayState определяется как

data ArrayState arr e a = MkArrayState (arr e -> (a, arr e)) 

Я думал, что это будет:

runArrayState act arr = ((act arr), arr) 

или

runArrayState MkArrayState (\ arr -> (res, arr)) arr' = (res, arr') 

, но все это не удается. Есть идеи?

+0

'ArrayState' имеет только один конструктор с одним аргументом. В почти каждой такой ситуации вместо этого вы должны использовать 'newtype'. – luqui

+1

О, кстати, вы получаете 'runArrayState' бесплатно, если вы определяете' ArrayState' в этом идиоматическом стиле: 'newtype ArrayState arr e a = MkArrayState {runArrayState :: arr e -> (a, arr e)}' – luqui

ответ

3

Я думаю

runArrayState (MkArrayState act) arr = act arr 

является то, что вы ищете.

Ваш тип ArrayState определяется как имеющий один конструктор MkArrayState, который имеет свой аргумент функцию, которая принимает массивы в пары, состоящие из результата и (предположительно) обновленного массива. В приведенном выше определении мы используем идентификатор act для ссылки на эту функцию и arr на массив, который мы имеем в качестве ввода. В правой части определения мы просто применяем функцию act к arr для получения требуемой пары.

В качестве альтернативы, вы можете определить свой тип, как

data ArrayState arr e a = MkArrayState {runArrayState :: arr e -> (a, arr e)} 

или (скорее всего) даже лучше,

newtype ArrayState arr e a = MkArrayState {runArrayState :: arr e -> (a, arr e)} 

Таким образом, вы будете иметь непосредственно определить функцию деструктора типа ArrayState arr e a -> arr e -> (a, arr e) (т.е. без ограничения класса, которое не требуется в вышеприведенной версии).

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