Skip to content

Instantly share code, notes, and snippets.

@PhilOwen
Last active November 5, 2016 07:52
Show Gist options
  • Save PhilOwen/02d6e00bf12f48e81818b6334ade0c59 to your computer and use it in GitHub Desktop.
Save PhilOwen/02d6e00bf12f48e81818b6334ade0c59 to your computer and use it in GitHub Desktop.
HaskellのPipesでCSVをストリーム処理

Haskellでストリーム処理を抽象化したPipesライブラリを使ってみる。

今回は、都道府県の面積のCSVファイルを読んだ。

stack build
stack exec hello-pipes < prefs.csv

で実行できる。 面積はkm2単位で、小数点以下は丸めた。

Pipesはメモリ消費が固定で、かなり効率的らしい。
かなり抽象化されているので、応用範囲が広く、 一般的なパースにも、並列プログラミングにも使えるらしい。 今回も、CSVのパーサにcassavaという ライブラリを組み合わせて使っている。

ただし、抽象的なだけあって、イメージしにくく難易度高め。 Producerが値を作って、Pipeで変換して、 Consumerで吐き出しているらしいが、 それぞれの関数の役割がすっきり理解できていない。 本来はドキュメントをもっとちゃんと読まないといけないが、 今回はまず使ってみるだけ。

References

name: hello-pipes
version: 0.1.0.0
build-type: Simple
cabal-version: >=1.20
executable hello-pipes
main-is: Main.hs
default-language: Haskell2010
default-extensions: OverloadedStrings
build-depends: base
, text
, cassava
, pipes
, pipes-bytestring
, pipes-csv
import qualified Data.Text as T
import Data.Csv ((.:), FromNamedRecord(..))
import Pipes
import Pipes.Csv (decodeByName)
import Pipes.ByteString (stdin, ByteString)
import Control.Applicative
data Prefecture = Prefecture T.Text Double
instance Show Prefecture where
show (Prefecture name area) = T.unpack name ++ ": " ++ show (round area) ++ "km2"
instance FromNamedRecord Prefecture where
parseNamedRecord p =
Prefecture <$> p .: "name"
<*> p .: "area"
prefs :: Monad m
=> Producer ByteString m ()
-> Producer (Either String Prefecture) m ()
prefs = decodeByName
main = runEffect $ for (prefs stdin) $ \(Right pref) -> do
lift $ putStrLn (show pref)
name area
北海道 83424.22
岩手県 15275.01
福島県 13783.75
長野県 13561.56
新潟県 12584.10
秋田県 11637.54
岐阜県 10621.29
青森県 9645.40
山形県 9323.15
鹿児島県 9188.10
広島県 8479.38
兵庫県 8400.90
静岡県 7778.70
宮崎県 7735.31
熊本県 7409.32
宮城県 7282.14
岡山県 7114.62
高知県 7103.91
島根県 6708.23
栃木県 6408.09
群馬県 6362.28
大分県 6340.61
山口県 6112.30
茨城県 6096.93
三重県 5774.39
愛媛県 5676.10
愛知県 5172.40
千葉県 5157.64
福岡県 4986.40
和歌山県 4724.68
京都府 4612.20
山梨県 4464.99
富山県 4247.61
福井県 4190.43
石川県 4186.15
徳島県 4146.93
長崎県 4132.32
滋賀県 4017.38
埼玉県 3797.75
奈良県 3690.94
鳥取県 3507.05
佐賀県 2440.64
神奈川県 2415.81
沖縄県 2281.00
東京都 2190.90
大阪府 1904.99
香川県 1876.73
resolver: lts-7.7
packages:
- '.'
extra-deps: []
flags: {}
extra-package-dbs: []
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment