2015-04-29 8 views
1

Приношу свои извинения, если мой вопрос глуп (я до сих пор совершенно не знаком с монадами), но до сих пор я не мог найти ответа на него.Haskell State monad с кортежами как состояние

Я хочу хранить пары как состояние в государственной монаде. Однако, если бы я попробовать это на простом примере (Int, Int) я получаю (GHCi):

Prelude> import Control.Monad.State 
Prelude Control.Monad.State> :t get :: State Int Int 
get :: State Int Int :: State Int Int 
Prelude Control.Monad.State> :t get :: State (Int, Int) Int 

<interactive>:1:1: 
    No instance for (MonadState 
         Int (StateT (Int, Int) Data.Functor.Identity.Identity)) 
     arising from a use of ‘get’ 
    In the expression: get :: State (Int, Int) Int 

Мои вопросы:
1. Почему?
2. Как мне заставить это работать?

+2

Если вы новичок в трансформаторах монады, импорт 'Control.Monad.Trans.State' вместо' Control.Monad.State' может упростить понимание (например, более четкие сообщения об ошибках и т. Д.) – ZhekaKozlov

+0

@ZhekaKozlov Теперь это интересно. Как вы и ожидали, моя оригинальная проблема была гораздо более сложной версией той, которую я представил в моем вопросе. Использование 'Control.Monad.Trans.State' помогло мне найти, где проблема на самом деле (и это была совсем другая вещь). Спасибо за этот комментарий, это помогло мне решить мою проблему. – Tommalla

+0

Добро пожаловать! – ZhekaKozlov

ответ

4

Тип get является

get :: State s s 

Так что если s = (Int, Int) то вы хотите

get :: State (Int, Int) (Int, Int) 

Вот и все. get возвращает весь кортеж.

+1

Это '=' должно быть '~', как в случае равенства типов, правильно? – AJFarmar

+2

Я не очень-то знаком с тем, что GHC использует для ограничений типа капитала; Я просто пытался написать то, что понимал бы средний человек. – MathematicalOrchid