2

Haskell の Text.JSON ライブラリは Result と呼ばれる抽象データ型を使用します。これは基本的には Maybe の形式ですが、Nothing の代わりに Error String があります。とにかく、JSON.readJSON の実装内で、liftIO を使用して、IO を返す関数呼び出しを Result に変換する必要があります。私はモナドトランスフォーマーに不慣れで、結果にliftIOを実装できないようです(ghciによると、無限型を構築しようとしています)。

何か案は?

どうもありがとう

編集

申し訳ありませんが、詳しく説明するのに時間がかかりました。皆さんの助けに感謝します。

  readJSON (JSObject obj) = do text <- getVal obj "text"
                           user <- getVal obj "from_user"
                           iden <- getVal obj "id_str"
                           url <- (do if (length.extractURLs) text == 0
                                           then return ""
                                           else return $ head $ extractURLs text)
                           title <- liftIO (getSiteTitle url)
                           return $ 
                            Tweet 
                              NewsStory {
                                          title = "Twitter",
                                          desc = text,
                                          url = url,
                                          metric = 0,
                                          sourceURL = "twitter.com/" ++ user  ++ "/status/" ++ iden
                                        }

したがって、return の前の最後の行では、getSiteTitle を使用して、その URL の Web サイトのタイトルを解析します。ただし、その関数は IO String の型を返し、コンパイラはそれを Result にしたいと言います。これは不可能ですか?

再度、感謝します!

EDIT2

データ型からタイトルを削除し、後で IO モナド内で取得することにしました。みんなの助けに感謝します!私は確かにこの問題から学びました。

4

3 に答える 3

5

readJSON 内で IO を使用することはできません (unsafePerformIO に頼らなければ)。liftIO は、下部に IO を持つモナド トランスフォーマーのスタックがある場合に使用されます。おそらく、あなたが達成しようとしていることのより具体的な情報を提供すれば、より有用な答えを得ることができるでしょう:)

于 2010-11-14T08:02:33.703 に答える
2

あなたが望むことは不可能です。jsonパッケージでは、readJSON :: JSValue -> Result a。定義上、これは純粋関数です。間違いなく、結果を内部のあるものにインスタンス化することはできますが、その場合、を実行することIOは不可能showJSON :: a -> JSValueです。

私の解決策は?データ型をatitle :: Maybe Stringにしてから、タイトルを入力するIOの2番目のパスを作成します。

于 2010-11-14T19:58:21.570 に答える
1

どの特定の JSON ライブラリを使用しているかはわかりませんが、似たような名前と名前空間を持つものが数十あります...

IO を使用して URL を取得したいので、関数を 2 つの関数に分割する必要があります。1 つは JSON モナド、もう 1 つは IO モナドです。IO モナドを「実行」できないため、IO 内で JSON モナドを実行する必要があります。ここで doAll は、2 つを結合するための追加の関数です。

使用している JSON ライブラリと一致するように少し編集する必要があります。タイプ シグネチャの一部が入力されておらず、JSON モナドの「実行」関数と戻り値の型がわかりません。

-- This one is in the JSON monad...
-- The type sig needs fixing...
readJSON :: JSObject ?? -> GetJSON (String,String,String,String)
readJSON (JSObject obj) = do 
    text <- getVal obj "text"
    user <- getVal obj "from_user"
    iden <- getVal obj "id_str"
    url <- (do if (length.extractURLs) text == 0
               then return ""
               else return $ head $ extractURLs text)
    return (text,user,iden,url)

-- This one is in IO...
ioStep :: (String,String,String,String) -> IO TweetNewsStory
ioStep (text,user,iden,url) = do
  title <- getSiteTitle url
  return $ TweetNewsStory {
             title = "Twitter",
             desc = text,
             url = url,
             metric = 0,
             sourceURL = "twitter.com/" ++ user  ++ "/status/" ++ iden
           }


-- Type sig needs fixing...
-- The JSON library will provide something similar to
-- runJSON...
--
doAll :: JSObject ?? -> IO TweetNewsStort
doAll jsobj = 
    let ans = runJSON $ readJSON jsobj in 
     case ans of 
       Left err -> error $ err
       Right val -> ioStep val
于 2010-11-14T15:49:24.373 に答える