Я пытаюсь вернуть значение, которое в корме 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 {...}
). Есть ли способ вытащить его или я использую неправильный подход?
Можете ли вы добавить все определения, которые используете. Трудно диагностировать проблему, не имея возможности запускать ее непосредственно через GHC. – Matt
Жаль, что вы совершенно правы. Я перепутал неправильные детали. Во всяком случае, я повторно отредактировал вопрос и поставил решение ниже. – Randomize
@ Randomize Считается, что правильная практика заключается в том, чтобы выставить решение в ответе, а не в вопросе. Это прекрасный этикет, чтобы ответить на ваш собственный вопрос. –