2015-06-27 4 views
1

Я пытаюсь вернуть значение, которое в корме JSon (через эсон) непосредственно внутри StateT сложенных на IO:Монада побега в контексте StateT

{-# LANGUAGE DeriveGeneriC#-} 
module MyFeed where 

import Data.Aeson 
import Network.URI (parseURI, URI(..)) 
import Data.Maybe (fromJust) 
import Data.Text (Text, unpack) 
import Control.Monad.State 
import Network.HTTP 
import GHC.Generics 
import Control.Applicative 
import Network.HTTP.Conduit (simpleHttp) 
import qualified Data.ByteString.Lazy as B 

type Feed a = StateT MyIndex IO a 

data MyIndex = MyIndex { 
    index :: Int 
} 

data FooBar = Foo | Bar 

data MyFeed = MyFeed { 
    idx :: !Text, 
    key :: !Text 
    } deriving (Show,Generic) 

instance FromJSON MyFeed 
instance ToJSON MyFeed 

getJSON :: String -> IO B.ByteString 
getJSON url = simpleHttp url 

getFeed :: String -> IO (Maybe MyFeed) 
getFeed url = (decode <$> getJSON url) :: IO (Maybe MyFeed) 

getIndex :: FooBar -> Feed MyIndex 
getIndex fb = do 
    cursor <- get 
    let newCursor = case fb of 
          Foo -> do myFeed <- liftIO $ getFeed "http://echo.jsontest.com/key/value/idx/1" 
             let i = read $ unpack $ idx $ fromJust myFeed 
             return $ cursor { index = i } 

          Bar -> return cursor 
    put newCursor 
    return newCursor 

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

src/MyFeed.hs:47:10: 
    Couldn't match expected type ‘MyIndex’ 
       with actual type ‘m0 MyIndex’ 
    Relevant bindings include 
     newCursor :: m0 MyIndex (bound at src/MyFeed.hs:40:7) 
    In the first argument of ‘return’, namely ‘newCursor’ 
    In a stmt of a 'do' block: return newCursor 

Actual Type выглядит еще в контексте Монада (do {...}). Есть ли способ вытащить его или я использую неправильный подход?

+0

Можете ли вы добавить все определения, которые используете. Трудно диагностировать проблему, не имея возможности запускать ее непосредственно через GHC. – Matt

+0

Жаль, что вы совершенно правы. Я перепутал неправильные детали. Во всяком случае, я повторно отредактировал вопрос и поставил решение ниже. – Randomize

+0

@ Randomize Считается, что правильная практика заключается в том, чтобы выставить решение в ответе, а не в вопросе. Это прекрасный этикет, чтобы ответить на ваш собственный вопрос. –

ответ

0

ошибка была из-за того, я использовал:

let newCursor = case fb of

вместо

newCursor <- case fb of

По этой причине окончательное значение никогда не получить «разворачивали» из контекста монады.

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