flymakeがあるのが当たり前になってしまっているので、Haskellで書いてる時にもダメなところはダメって言ってもらわないとちょっと気持ち悪い。
Haskellでもflymakeを使えるようにするためにMac/emacsでHaskell環境を作るを参考に自分のflymake-init.elに追加した。
ついでにhaskell-modeも新しいのを入れるためにgit cloneしておいた。
おまけ
- Mac/emacsでHaskell環境を作るにあったel-getが気になるので後で調べる
flymakeがあるのが当たり前になってしまっているので、Haskellで書いてる時にもダメなところはダメって言ってもらわないとちょっと気持ち悪い。
Haskellでもflymakeを使えるようにするためにMac/emacsでHaskell環境を作るを参考に自分のflymake-init.elに追加した。
ついでにhaskell-modeも新しいのを入れるためにgit cloneしておいた。
おまけ
13062012 Haskell
13062012 Haskell
yesodをインストールしようとしたら、エラーを吐いた。(Haskell Platform 2012.2.0.0 for Mac OS X, 32 bit)
$ cabal install yesod-platform Resolving dependencies... Configuring ranges-0.2.4... Preprocessing library ranges-0.2.4... Building ranges-0.2.4... [1 of 1] Compiling Data.Ranges ( Data/Ranges.hs, dist/build/Data/Ranges.o ) Data/Ranges.hs:9:6: Illegal datatype context (use -XDatatypeContexts): Ord a => cabal: Error: some packages failed to install: email-validate-0.2.8 depends on ranges-0.2.4 which failed to install. ranges-0.2.4 failed during the building phase. The exception was: ExitFailure 1
rangesを別にインストールしてみたらもうちょい詳しいエラーが出た。
$ cabal install ranges-0.2.4 Resolving dependencies... Configuring ranges-0.2.4... Preprocessing library ranges-0.2.4... Building ranges-0.2.4... [1 of 1] Compiling Data.Ranges ( Data/Ranges.hs, dist/build/Data/Ranges.o ) Data/Ranges.hs:9:6: Illegal datatype context (use -XDatatypeContexts): Ord a => cabal: Error: some packages failed to install: ranges-0.2.4 failed during the building phase. The exception was: ExitFailure 1
ranges-0.2.4をダウンロードしてきて
runghc Setup configure --prefix="$HOME/.cabal" --user runghc Setup build runghc Setup install
って普通にいれたら入った。
あとは再度上の手順でyesodをインストールした。
11062012 Haskell
朝カットに行って髪を切ってもらっている間、タイトルのようなことを考えていた。
Prelude Control.Arrow> :i (->) data (->) a b -- Defined in `GHC.Prim' Prelude Control.Arrow> :k (->) (->) :: * -> * -> *
であり、(->)は型として定義されている。すごいHaskell(p.232)の言葉を借りれば、適用しろという文脈の着いた型と考えればいいんだろう。
部分適用((->) r)のfmapは(.)なので関数合成なんだが、そういえばArrowか?などとControl.Arrowを探索しはじめた。
Prelude Control.Arrow> :i (.) (.) :: (b -> c) -> (a -> b) -> a -> c -- Defined in `GHC.Base' infixr 9 . Prelude Control.Arrow> :i (>>>) (>>>) :: Control.Category.Category cat => cat a b -> cat b c -> cat a c -- Defined in `Control.Category' infixr 1 >>> Prelude Control.Arrow> :i (<<<) (<<<) :: Control.Category.Category cat => cat b c -> cat a b -> cat a c -- Defined in `Control.Category' infixr 1 <<<
というわけで、(.)と(<<<)は同等のものかな。
(.) :: (b -> c) -> (a -> b) -> a -> c
これは部分適用((->) r)を使えば
(b -> c) -> ((->) a b) -> ((->) a c)
結局(->)をcatに書き換えれば同じ物ができる。そういうあたりから考えるとArrowは関数合成を拡張(一般化?)したものと考えればいいのかなぁ。
とか考えていくうちに関数型の値コンストラクタって一体なんじゃろかねーという疑問が湧いてくるわけで。
14章で状態付きの計算をやったときとかのStateモナドはrunStateで計算をはしらせたけど、関数型はそういうのがないからなぁ、適用しろっていう文脈を持った型なのに、じゃぁどのタイミングで適用すんのよ?とよく分からなくなってきた。
暗黙的な何かなのか、それともそもそも自分の理解がどこか間違っているのか?
値コンストラクタと型コンストラクタをきちんと理解してなかった。型コンストラクタの型変数は引数として取るものだと思っていたが、単に型変数を表しているだけなのね。
data Maybe a = Nothing | Just a -- Defined in `Data.Maybe' data Either a b = Left a | Right b -- Defined in `Data.Either'
なんだけど
read :: Read a => String -> a
見たら、なんか間違っていたと理解した。
それから、RWHのp.228
type InfoP a = FilePath -> Permissions -> Maybe Integer -> ClockTime -> a
01062012 Haskell
これは、僕のなかで非常に納得のいくものだった。
Haskell以外のほとんどの言語における「代入」という操作は、状態付きの計算と捉えることができます。
MooseやPythonでlispとかschemeを書いたことがあったが、そのときに環境というスタックを用意したなぁと妙に納得した。
この本は、日本の初級Haskellerのレベルを押し上げる役割を担うんじゃないかなぁと。少なくとも僕は本書を読んだことで、haskell細胞が進化した(by トリコ)
それからWriterモナドが面白いなぁと改めて思ったので写経。
import Control.Monad.Writer gcd' :: Int -> Int -> Writer [String] Int gcd' a b | b == 0 = do tell ["Finished with " ++ show a] return a | otherwise = do tell [show a ++ " mod " ++ show b ++ " = " ++ show (a `mod` b)] gcd' b (a `mod` b)
実行すると、ログがついて回るのでsndで抜き出す。
*Main> mapM_ putStrLn $ snd $ runWriter (gcd' 4351 3776) 4351 mod 3776 = 575 3776 mod 575 = 326 575 mod 326 = 249 326 mod 249 = 77 249 mod 77 = 18 77 mod 18 = 5 18 mod 5 = 3 5 mod 3 = 2 3 mod 2 = 1 2 mod 1 = 0 Finished with 1
Haskellはやっぱり面白いなぁ。もう少し書けるようになりたい。
27052012 Haskell
引き続き「すごいHaskellたのしく学ぼう」を読んでいる。
ApplicativeとMonadの違いはbind(>>=)があるかどうかだと思うんだけど
(>>=) = m a -> (a -> m b) -> m b
これは、
モナド値を取って、それに「通常の値を取るがモナド値をとる返す関数」を適用する
わけだ。そしてこれは、Applicativeのススメによると、Applicativeでは条件分岐は実現できず(Monadではできる)ということになるんだと思うわけで、そこら辺の分かりやすい説明が13.4の綱渡りに書かれている。
で、書かれている関数は理解できるんだが、意図しているものがモヤモヤしている。この例の場合の条件分岐はNothingかJust xで型(データコンストラクタ?)が別れるということになるんだろうなぁと思うんだけど、じゃぁMaybe型ってなんなの?
失敗するかもしれないという文脈付きの型って本書では書いてあるけど、モナドから見たら失敗している、失敗してないという2つの状態を表現している型 っていう認識でいいのか?bindはその二つのいずれかに条件分岐できるという。
アプリカティブ値が相互作用できない(モナド値が相互作用できる)てそういうこと?
26052012 Haskell
この本は10章まではウォーミングアップみたいなもので11章からが本番です。
Applicativeに関してはあどけない話のApplicativeのススメを読んだ時にいまいちよく分からなかったのだけど、11章はFunctorから始めて、自然な流れでApplicativeの説明がしてあって非常に分かりやすい。もし、モナドを理解しているなら頭にこんな図を描きながら読むといいです。
<*>は関数の入っているファンクター値と値の入っているファンクター値を引数に取って、一つ目のファンクターの中身の関数を2つ目のファンクターの中身に適用する
ということなので、pure f <*> xはfmap f x と等しく、f <$> xとも書ける。
理解した上でもう一度あどけない話のApplicativeのススメを読むと楽しいですね。
あとでパーサー書いてみようっと
24052012 Haskell
13052012 Haskell javascript
アルゴリズムの本。いまいち読む気分になれない
Titanum Mobileは興味があるので次に読む本としてはこれが候補かな。
これは流し読みしたら途中で挫折したので、今度は丁寧に読む予定
予約してあるやつ
01052012 Haskell