0

これは実際には、私が数日前に尋ねた質問の続きです。アプリカティブ ファンクター ルートを使用して、独自のインスタンスを作成しました。

ファイル内の膨大な数の json ステートメントを 1 行ずつ解析する必要があります。json ステートメントの例は次のようなものです -

{"question_text": "How can NBC defend tape delaying the Olympics when everyone has
Twitter?", "context_topic": {"followers": 21, "name": "NBC Coverage of the London
Olympics (July & August 2012)"}, "topics": [{"followers": 2705,
"name": "NBC"},{"followers": 21, "name": "NBC Coverage of the London 
Olympics (July & August 2012)"},
{"followers": 17828, "name": "Olympic Games"},
{"followers": 11955, "name": "2012 Summer Olympics in London"}], 
"question_key": "AAEAABORnPCiXO94q0oSDqfCuMJ2jh0ThsH2dHy4ATgigZ5J",
"__ans__": true, "anonymous": false}

json形式でごめんなさい。悪くなった

このような json ステートメントが約 10000 個あり、それらを解析する必要があります。私が書いたコードは次のようなものです -

parseToRecord :: B.ByteString -> Question
parseToRecord bstr = (\(Ok x) -> x) decodedObj where decodedObj = decode (B.unpack bstr) :: Result Question

main :: IO()
main = do
  -- my first line in the file tells how many json statements
  -- are there followed by a lot of other irrelevant info...
  ts <- B.getContents >>= return . fst . fromJust . B.readInteger . head . B.lines
  json_text <- B.getContents >>= return . tail . B.lines
  let training_data = take (fromIntegral ts) json_text
  let questions = map parseToRecord training_data
  print $ questions !! 8922

このコードで実行時エラーが発生しますNon-exhaustive patterns in lambda。エラー\(Ok x) -> xは、コード内の を参照しています。試行錯誤の結果、プログラムは 8921 番目のインデックスまで正常に動作し、8922 番目の反復で失敗するという結論に達しました。

対応するjsonステートメントを確認し、関数を呼び出してスタンドアロンで解析しようとしましたが、機能しました。ただし、 mapを呼び出すと機能しません。何が起こっているのかよくわかりません。「大きな利益のために Haskell を学ぶ」で Haskell を少し学んだので、現実世界のプログラミング プロジェクトに飛び込みたいと思っていましたが、ここで立ち往生しているようです。

編集::完全なコードは次のとおりです

{-# LANGUAGE BangPatterns #-}
{-# OPTIONS_GHC -O2 -optc-O2 #-}
{-# OPTIONS_GHC -fno-warn-incomplete-uni-patterns #-}
import qualified Data.ByteString.Lazy.Char8 as B
import Data.Maybe
import NLP.Tokenize

import           Control.Applicative
import           Control.Monad
import           Text.JSON

data Topic = Topic
  { followers :: Integer,
    name :: String
  } deriving (Show)

data Question = Question
  { question_text :: String,
    context_topic :: Topic,
    topics :: [Topic],
    question_key :: String,
    __ans__ :: Bool,
    anonymous :: Bool
  } deriving (Show)

(!) :: (JSON a) => JSObject JSValue -> String -> Result a
(!) = flip valFromObj

instance JSON Topic where
  -- Keep the compiler quiet
  showJSON = undefined

  readJSON (JSObject obj) =
    Topic       <$>
    obj ! "followers" <*>
    obj ! "name"
  readJSON _ = mzero

instance JSON Question where
  -- Keep the compiler quiet
  showJSON = undefined

  readJSON (JSObject obj) =
    Question      <$>
    obj ! "question_text"   <*>
    obj ! "context_topic" <*>
    obj ! "topics" <*>
    obj ! "question_key" <*>
    obj ! "__ans__" <*>
    obj ! "anonymous"
  readJSON _ = mzero

isAnswered (Question _ _ _ _ status _) = status
isAnonymous (Question _ _ _ _ _ status) = status

parseToRecord :: B.ByteString -> Question
parseToRecord bstr = handle decodedObj
                        where handle (Ok k)     = k
                              handle (Error e)  = error (e ++ "\n" ++ show bstr)
                              decodedObj = decode (B.unpack bstr) :: Result Question
--parseToRecord bstr = (\(Ok x) -> x) decodedObj where decodedObj = decode (B.unpack bstr) :: Result Question

main :: IO()
main = do
  ts <- B.getContents >>= return . fst . fromJust . B.readInteger . head . B.lines
  json_text <- B.getContents >>= return . tail . B.lines
  let training_data = take (fromIntegral ts) json_text
  let questions = map parseToRecord training_data
  let correlation = foldr (\x acc -> if (isAnonymous x == isAnswered x) then (fst acc + 1, snd acc + 1) else (fst acc, snd acc + 1)) (0,0) questions
  print $ fst correlation

実行可能ファイルへの入力として指定できるデータは次のとおりです。私はghc 7.6.3を使用しています。プログラム名が ans.hs の場合、次の手順に従いました。

$ ghc --make ans.hs
$ ./ans < path/to/the/file/sample/answered_data_10k.in

どうもありがとう!

4

2 に答える 2

0

Maybenull 値を解析するために使用する提案があります。

data Question = Question
  { question_text :: String
  , context_topic :: Maybe Topic
  , topics :: [Topic]
  , question_key :: String
  , __ans__ :: Bool
  , anonymous :: Bool
  } deriving (Show)

次に、readJSON関数を次のように変更します (さらに、欠落しているansFalseフィールドは、解析の試みが失敗した場合に戻ることで修正できます)。

instance JSON Question where
  -- Keep the compiler quiet
  showJSON = undefined

  readJSON (JSObject obj) = Question <$>
    obj ! "question_text"   <*>
    (fmap Just (obj ! "context_topic") <|> return Nothing) <*>
    obj ! "topics" <*>
    obj ! "question_key" <*>
    (obj ! "__ans__" <|> return False) <*>
    obj ! "anonymous"
  readJSON _ = mzero

1000インライン 9000 のようなもの (sabauma が述べたように) を取り除いた後4358、結果として得られました。では、これらのわずかな変更で十分でしょうか?

于 2013-07-30T18:40:04.460 に答える