Haskellでもmkvirtualenvとworkonが使いたい

Pythonにはvirtualenvwrapperというvirtualenvをより快適につかうためのパッケージがあって、インストールするとmkvirtualenvとworkonというコマンドが使えるようになり、散らばりがちな仮想環境をきちんと管理できるようになるので、一度使うと手放せない。

Haskellでもvirtualenvクローンのvirthualenvを使っているのでmkvirtualenv相当のツールが欲しくなるのは必然。

mkvirthualenvというコマンドを書いた。

import System.Directory
import System.FilePath
import System.Process
import System.Environment

getVirthualenvDir :: IO FilePath
getVirthualenvDir = do
  home <- getHomeDirectory
  return $ home </> ".virthualenv"

main :: IO ()
main = do
  (newenv:_) <- getArgs
  currentDir <- getCurrentDirectory
  vdir <- getVirthualenvDir
  createDirectoryIfMissing True vdir
  createDirectoryIfMissing True $ vdir </> newenv  
  setCurrentDirectory $ vdir </> newenv
  _ <- system "virthualenv" 
  setCurrentDirectory $ currentDir
  return ()

workhonはbashの関数にしてみた。

function workhon(){ source $HOME/.virthualenv/$1/.virthualenv/bin/activate; }

要するに.virthualenvっていうディレクトリでそれぞれの仮想環境を管理するようにしているので、要らなくなったら該当するディレクトリを消せばいいだけ。

例えばHakyll用の仮想環境を用意したい場合、

mkvirthualenv hakyll
workhon hakyll
cabal install hakyll

こんな感じ。仮想環境をぬけるのは

deactivate

入るのがworkhonで出るのがworkhoffじゃなくてdeacivateなのは何でじゃ?っていう疑問も本家Pythonゆずりということで。

たった6行のコードでひたすらアイドル水着画像をあつめる(Haskell)

普段はrequests+pyqueryでやるが、今はHaskell強化月間なのでHandsomeSoupを使ってみた。

import Text.HandsomeSoup
import Text.XML.HXT.Core
main = do
  doc <- fromUrl "http://matome.naver.jp/odai/2135350364969742801"
  links <- runX $ doc >>> css ".MTMItemThumb" ! "src"
  mapM_ (putStrLn . show) links

調べてわかったんだが、Haskellって意外とスクレイピング用のライブラリが充実していた。

Hakyll+bootstrapでGithub Pagesをつくった

次回の三島Haskell無名の関数の会は懇親会を鈴木屋@三島でやることが決定しているので、前回のホルモン画像を使ってみた。

鈴木屋

使ったもの

Shizudevつくる会でbootstrapの勉強会をやりたいなーと思っているんだけど誰か興味ある人いないじゃろか?

Haskellのarrは何を持ち上げるのかがちょっと分かった気になった

Hakyllのサンプルを読んでいてarrowの使い方がわかりやすくていいなーと思ったんだがarrの必要性がよく分からなかった。

例えばtagblogの22行目のarrとか。

>>> arr (renderDateField "date" "%B %e, %Y" "Date unknown")

renderDateFieldは

renderDateField :: String  -- ^ Key in which the rendered date should be placed
                -> String  -- ^ Format to use on the date
                -> String  -- ^ Default value, in case the date cannot be parsed
                -> Page a  -- ^ Page on which this should be applied
                -> Page a  -- ^ Resulting page
renderDateField = renderDateFieldWith defaultTimeLocale

だからrenderDateField "date" "%B %e, %Y" "Date unknown"の型は

Page a -> Page a

でarrで持ち上げる必要ないんじゃないかなぁと。

と思ったので、22行目のarrを除いてコンパイルしてみた。

$ ghc --make test.hs 
[1 of 1] Compiling Main             ( test.hs, test.o )

test.hs:22:17:
    Couldn't match expected type `Compiler (Page String) b0'
                with actual type `Page a0 -> Page a0'
    In the return type of a call of `renderDateField'

あれ?arrってCompiler型に持ち上げていたのか。ということはCompiler型ってAllowなのか

みてみると、

data Compiler a b = Compiler
    { compilerDependencies :: Reader DependencyEnvironment Dependencies
    , compilerJob          :: a -> CompilerM b
    }

あーなるほど。こういうのもArrowになるのか。

というわけで、arrの使い道がちょっと分かった(気がした)。

hsktagsでHaskellでもタグジャンプ

@karky7に教えてもらったEmacsのタグジャンプでRedmineの中を探索するのが楽になったが、etagsはHaskell対応していない。

これは困ったとフグったところ、hasktagsをみつけて解決。

hakyllのソースで

hasktags -e .

ってやってTAGSファイルを作ったら、Emacsでタグジャンプできる。

HaskellでRSSを読み込む

以前書いたのを今みるとグダグダだ。やっぱコピペはダメだな。

今回feedを使ってみた。ファイルの読み込みだったらparseFeedFromFileを使う。

import Text.Feed.Import
import Text.Feed.Query
import Data.Maybe

main = do
  rss <- parseFeedFromFile "test.rss"
  mapM_ putStrLn $ map (fromJust . getItemTitle) (getFeedItems rss)

HTTPと組み合わせる場合は

import Text.Feed.Import
import Text.Feed.Query
import Data.Maybe
import Network.HTTP

eutils_url = "http://eutils.ncbi.nlm.nih.gov/entrez/eutils/erss.cgi?rss_guid="
guid = "1ZQ4a7JQ6X8P3NJNZLWG_ML-XsrLQgH63A06CsXO-jG0m_iEe-"

getTitle = (take 60) . fromJust . getItemTitle
getItems = getFeedItems . fromJust . parseFeedString

main :: IO ()
main = do
  res <- simpleHTTP $ getRequest $ eutils_url ++ guid
  body <- getResponseBody res
  mapM_ putStrLn $ map getTitle $ getItems body

実行すると

RMol: A Toolset for Transforming SD/Molfile structure inform
Adenosiland: Walking through adenosine receptors landscape.
Enzyme Informatics.
The Use of the R language for Medicinal Chemistry Applicatio
Similarity coefficients for binary chemoinformatics data: ov
Review on Chemogenomics approach: Interpreting antagonist ac
Immunotoxicity, Flow Cytometry and Chemoinformatics: A Revie
A Parallel Systematic-Monte Carlo Algorithm for exploring Co
Validation of drug-like inhibitors against Mycobacterium tub
Desirability-based Multi-criteria Virtual Screening of Selec
The use of glycoinformatics in glycochemistry.
Role of computational methods in pharmaceutical sciences.
High-throughput screening with a miniaturized radioligand co
Chemoinformatics: recent advances at the interfaces between 
ReactionPredictor: Prediction of Complex Chemical Reactions

プロキシとかセッションなんかを使いたい場合にはNetwork.Browserを利用する。

Network.Browserは以下の機能が使えるハイレベルなモジュール。

  • HTTP Authentication handling
  • Transparent handling of redirects
  • Cookie stores + transmission.
  • Transaction logging
  • Proxy-mediated connections.

browseのところに色々挟みこむとよろしくやってくれる(今回はなんもしてないけど)。職場で使う時にはプロキシを挟む必要があるためsimpleHTTPは使えない。

import Text.Feed.Import
import Text.Feed.Query
import Data.Maybe
import Network.HTTP
import Network.Browser (browse, request)

eutils_url = "http://eutils.ncbi.nlm.nih.gov/entrez/eutils/erss.cgi?rss_guid="
guid = "1ZQ4a7JQ6X8P3NJNZLWG_ML-XsrLQgH63A06CsXO-jG0m_iEe-"

getTitle = (take 60) . fromJust . getItemTitle
getItems = getFeedItems . fromJust . parseFeedString . rspBody

main :: IO ()
main = do
  (_, res) <- browse $ do
    request $ getRequest $ eutils_url ++ guid
  mapM_ putStrLn $ map getTitle $ getItems $ res

ちなみにRMolにはいまいち惹かれないなぁ。Rならではのメリットあるんだろうか?

HaskellでSQLiteにアクセスする

Haskell力をあげるために、少しの間Pythonを封印してみることにした(職場で)。

いつもならSQLAlchemyを使うところでHDBCを使っているが、本を読んで分かった気になっていただけだったと思い知らされた。

使ってみてDBIっぽいなぁと思ったらゆるく参考にしているらしい

HDBC is modeled loosely on Perl's DBI interface http://search.cpan.org/~timb/DBI/DBI.pm, though it has also been influenced by Python's DB-API v2, JDBC in Java, and HSQL in Haskell. Database.HDBC

結果のフェッチの仕方を調べてみると用途に応じて色々なやり方で結果を返すことができるようになっていた。

  • listで返すかassociation listで返すか、それともMapで返すか
  • 正格、非性格
  • 全てのrowを返すか、一つを返すか
  • SQLValue型かMaybe String型で返すか

必ず答えが返ってくるのが分かっているなら、Maybe Stringで返してfromJustでstringにすればいい。自分のブログ(Flask製)のdatabaseを使ってみる。

import Database.HDBC
import Database.HDBC.Sqlite3
import Data.Maybe

main = do
  conn <- connectSqlite3 "/Users/kzfm/blog.db"
  stmt <- prepare conn "select title from entry"
  execute stmt []
  results <- sFetchAllRows stmt
  mapM_ (putStrLn . fromJust) $ concat results

RWHの日本語版のEpubかmobiが欲しいなぁ。

ProductName Real World Haskell―実戦で学ぶ関数型言語プログラミング
Bryan O'Sullivan
オライリージャパン / 3990円 ( 2009-10-26 )


fayを使えと心に直接呼びかけられた

(……きこえますか…きこえますか…JSerの…みなさん… 三島Ha…無名…会です… 今… あなたの…心に…直接… 呼びかけています…フロントエンドは…underscore.jsを…使う場合では…ありません…あなたが…使う…言語は… Clojure某でも…ありません…Haskellです…Haskellを…使うのです…fayでコンパイルするのです…)

fayはHaskellコードをjavascriptにコンパイルするツールで最近精力的に開発が進んでいるようで素晴らしいですね、心に呼びかけられるのも納得です。

import Language.Fay.Prelude

mylist :: [Int]
mylist = [1..10]

-- test
main :: Fay ()
main = print $ any (==2) mylist

fayコマンドでhaskellをjavascriptにコンパイルすればnode.jsで動かせるようになります。

$ fay test.hs 
$ node test.js 
true

underscore.jsに載ってた他の関数もこんな感じ。findなんかはMaybe型で返ってくるので値がなかった場合の処理も楽ちんです。

-- each
mapM_ print mylist

-- map
map (3*) mylist

-- reduce
foldl (+) 0 mylist

-- reduceRight
foldr (+) 0 mylist

-- find
find even mylist

-- filter
filter even mylist

-- reject
filter (not . even) mylist

-- all
all (>0) mylist

-- any
any (>5) mylist

-- contains
any (==2) mylist

すごいHaskellをKindleで読む時が来ましたね!これは内側からなぜか湧き上がる物欲ですが、、、、

ProductName すごいHaskellたのしく学ぼう!
Miran Lipovaca
オーム社 / ?円 ( 2012-09-21 )


ProductName Kindle Paperwhite

Amazon.co.jp / 7980円 ( 2012-11-19 )


三島Haskell無名関数の会は一緒にHaskellを学ぶお友達を絶賛募集中です。今度は三島でHaskell勉強してホルモン食べながらビールを飲みます。

Haskellでマルコフ連鎖

Titanium Mobileがうまくいかないのだが、さすがに二三日で解決しないと気が滅入るので気分転換。

virthualenv 
source .virthualenv/bin/activate 
cabal install markov-chain

コードを書く。文章は魯山人(青空文庫)から。Kindle買ったら魯山人は全部入れておくといいですね。

import System.Random
import Data.MarkovChain

mytext = "かつおぶしはどういうふうに選択し、どういうふうにして削るか。まず、かつおぶしの良否の簡単な選択法をご披露しよう。よいかつおぶしは、かつおぶしとかつおぶしとをたたき合わすと、カンカンといってまるで拍子木か、ある種の石を鳴らすみたいな音がするもの。虫の入った木のように、ポトポトと音のするしめっぽいにおいのするものは悪いかつおぶし。本節と亀節ならば、亀節がよい。見た目に小さくとも、刺身にして味い大きいものがやはりかつおぶしにしても美味だ。見たところ、堂々としていても、本節は大味で、値も亀節の方が安く手に入る。次に削り方だが、まず切れ味のよいかんなを持つこと。切れ味の悪い鉋ではかつおぶしを削ることはむずかしい。あかさびになったり刃の鈍くなったもので、ゴリゴリとごつく削っていたのでは、かつおぶしがたとえ百円のものでも、五十円の値打ちすらないものになる。"

result = take 200 $ run 2 mytext 0 (mkStdGen 123)

main = putStr result

実行

かつおぶしは、かつおぶしの良否の簡単な選択し、どういうふうに、ポトと音のするものがやはりかつおぶしを削ること。切れ味の悪いかつおぶしを削ること。切れ味の悪いかつおぶしはどういうふうに、ポトポトポトポトと音のするしめっぽいにおいのするしめっぽいにおいのするしめっぽいにおいのするものは悪いかつおぶしを削るか。まず、かつおぶしの良否の簡単な選択し、どういうふうにして味い大きいものになった木のよう。よい。

日本語は形態素解析が必須だなと。

三島Haskell無名関数の会#1が面白かった

皆様お疲れ様でした。Emacsの設定ネタでやたらと時間が取られてしまったが、Emacsの素晴らしさが伝えられたかなーと。キーバインドなんて些細なことですよ、みんな左手の小指を鍛えて快適なEmacsライフをおくりましょう!

init.elはこれを参考にしてください。

todo

virtualboxでGentoo Linuxを入れてみる。

次回

fay-langの話とか、もう少しハンズオン的なyesod(wikiを作るくらいの)ネタをやれればいいかなという感じ。

次回は三島でやって、懇親会を鈴木屋でやりたい。

参加者