haskell-jp / questions #55

@ has joined the channel
返信遅くなりすみません
Haskellのプロセスの起動までは大した時間がかからないのですが、そのプロセスの中でDynamoDBやS3にアクセスすると、長大な時間がかかるのです。
node.jsでDynamoDBにアクセスしてそれをHaskellに渡す、というのは確かに1つの方法ではありますが、できればHaskellでなるべく多くの仕事をしたいと思っています。
@y-tsune has joined the channel
@zfhrp7 has joined the channel
@πk has joined the channel
皆さんありがとうございました。今回は、as_cabal さんの方法を使うことにしました。既に組み上げたものにちょっと足すだけで、やりたかったことが実現できました。
私もnode.jsからはeventのデータだけしかやりとりせずに
DynamoDBやS3とは直接やりとりしていますが、
そもそもそのプログラムはAWS Lambdaでなければアクセスは速いのですか?
ローカル環境で動かすと1秒もかからないですね。
@CYBAI has joined the channel
@CycloneT has joined the channel
@ has joined the channel
@ has joined the channel
ざっくりした質問で恐縮なんですが、cabal new-buildってどういう仕組みでcabal sandboxや古いcabal buildの問題点を解決しているんでしょうか。参考になるリンクでも良いので教えてください! hask(_ _)eller
Nix-style というだけあって、 Nix ぽいです。もし Nix を知っていれば、類推でなんとなくつかめるかもしれません。端的にいえば、 sandbox に加えて、ライブラリのビルドキャッシュがホームディレクトリ単位になったものと理解しています。
古い cabal build は同一ライブラリの複数バージョンを持てませんでしたが、 new-build は sandbox 相当の機能を持っているのでこれを解消しています。
sandbox はプロジェクト毎に分離されていたので、プロジェクト間でライブラリのビルドが重複してしまいます。 new-build ではホームディレクトリ単位でキャッシュされているので、同じライブラリの同じバージョンのビルドは全体で一回ですみます。

というのが自分の理解ですが、本格的に調べたわけではないので違うところがあったらごめんなさい。
参考になるドキュメントはとりあえず公式の https://cabal.readthedocs.io/en/latest/nix-local-build-overview.html を挙げておきます……
ビルドの成果物に影響を及ぼす入力、例えばソースコードの内容、各種GHCフラグ、依存パッケージのバージョンなどから一意に決まるハッシュ値を計算して、ハッシュ値ごとに成果物をstoreにキャッシュして、同じハッシュ値を使うビルドにはキャッシュの内容を再利用するとりかいしてます
Hutton本2でDefunctionalizationなるテクニックが使われています。
どうも、関数をデータ構成子で置き換えることのようです。
https://en.wikipedia.org/wiki/Defunctionalization
この説明中の first-order と higher-order は、どういう意味でしょうか?
あと、Defunctionalizationの訳語があれば、教えてください。
「関数の除去」ぐらいでいいかなとは思っています。
大体わかりました!ドキュメントも読んでみます!
ありがとうございます!
一般的な語法通り、高階関数とそうでない関数のことだと思います。化学用語などに倣ってあえて訳すとすれば「脱関数」でしょう
Higher-Order Programming Languagesの所であれば「高階関数を扱う」というくらいに考えていました.
first-orderはhigher-orderの対義語くらいの意味なんだと思います.
The M-language of McCarthy (1960) is first order, as there is no provision to pass a function as argument or return a function as result5.
https://www.cs.kent.ac.uk/people/staff/dat/tfp12/tfp12.pdf
Hutton2 では、高階関数を置き換える感じじゃないんです。関数を構成子に置き換えるだけ。
Hutton2では、first-orderを訳さない方向で検討します。
wikipediaのexampleのやっていることは分かったけどLamを差し込む意義が良く分からないな...
このexampleを見る限りTreeとLamは完全に同型なのでだから何?みたいな.
そうか関数と構成子の違いってパターンマッチできるとかcase splitできる点にあることを考えると,Lamがexampleの例のままだと非力すぎるってことなのかな.
Lamの構成子を豊かにしてやれば差が見えてくる?
C言語に直して言うと「関数ポインタを引数に取る関数(高階関数)があって、それに指定される関数ポインタがすべて分かっているとき、関数ポインタをenum、その呼び出しをswitchに置き換える」という最適化なのだと理解しました
で、enumをもっと複雑な代数データ型に拡張できるよというのがDefunctionalizationの要点で、それがLamなのか
Defunctionalizationは"functional"を除去するという意味じゃないかと思います。functional(汎関数)はHigher-order functionの別名の一つです。 https://en.wikipedia.org/wiki/Higher-order_function
@cutsea110 Hutton2 では、導出したコンパイラ&仮想マシンから、継続(関数)を取り除いて、仮想マシンのコマンドに変えています。ので、かなり意味があります。
https://blog.poisson.chat/posts/2018-08-06-one-type-family.html の普通の関数版のお話ってことですかね。
具体的には、

addC :: Cont -> Cont




data Code = HALT | PUSH Int Code | ADD Code
                 deriving Show


ADD で置き換えます。

type Cont = Stack -> Stack


なので、 addC は高階関数ですね。

脱高階関数と訳そうかな。。。
関数のままだと適用されて計算が進んじゃうけどデータ構成子を被せればWHNFで一旦ストップするからコンパイラが手を出せる、最適化などが出来るってところかな.狙いとしては.
SICPの積極制御評価器ぽいネタだ.おもしろそう.
数式の eval 関数が、コンパイラcompと仮想マシンexecに分離され、その間が Code で取り持たれます。
プログラム解析の文脈ですと一階のプログラム(Cなど)の解析手法(抽象解釈など)で関数オブジェクトを扱いたいときに使われているとおもいます。いわゆるクロージャ変換のことを指すこともある気がします。
https://typesandkinds.wordpress.com/2013/04/01/defunctionalization-for-the-win/
これなんかはそれに近い話をしてるのかなぁ
shiatsumat さんは脱関数化と訳してるっぽいですね.脱高階関数化の方が適切だとは思います
https://github.com/shiatsumat/fp-papers/wiki/%E8%84%B1%E9%96%A2%E6%95%B0%E5%8C%96%E3%82%92%E5%AE%9F%E7%94%A8%E3%81%99%E3%82%8B
そうかwalk_defがcompでapplyがexecと.
今exampleを冷静にみたら確かに脱高階関数してる…のか?
単に「コンパイラ Defunctionalization」でググって見つけた情報ですが、以下の論文では「非関数化」と訳しているみたいです。
ちなみに「非関数化」の説明は、
「非関数化とは他から独立している関数を一階のオブジェクトに置き換える変換で,関数を返す部分をそのオブジェクトを返すように変更し,そのオブジェクトを処理するための apply 関数を別に用意する,というものである.」
とあります。
http://pllab.is.ocha.ac.jp/~asai/jpapers/ppl/kitani10.pdf
初歩的な質問で申し訳ないのですが
なぜ(baseライブラリの) Functor はDataに属してるのでしょうか? 関連する Monad, Applicative, BiFunctor は Controlに属しているのに
Applicativeは逐次実行、Monadは分岐という制御能力がありますが、Functorにはないからではないでしょうか?もっとも、ControlとDataの区別はかなり曖昧ではあると思います
あれ、 BiFunctor って Control にも Data にもあるようですが、 Control の方ってたぶん古いような感じがするんですがどうなんでしょうか
ついでに元の話について思うところを書くと、 Functor は Traversable の親でもあるので、さすがに Control.Traversable は違和感があるのでそこまではひっくるめて Data っていうニュアンスなんじゃないかなあ、という気がします
@Makoto Hamana has joined the channel
こんにちは。いつもお世話になります。
ファイルの書き出しを正格に(?)実行する方法はありますか?

do 構文の中で、
writeFile ( http://hackage.haskell.org/package/bytestring-0.10.8.2/docs/Data-ByteString.html#g:28 )に filepathとコンテンツを渡したあと、このfilepathのファイルを別のところに送信するプログラムを書いているのですが、 writeFile呼び出し直後にはファイルが存在しないことがあります。

writeFileの同期処理についてグーグルで検索すると、
readFileの内容を`seq`で評価して`writeFile`に渡す、という例は多数見つかるのですが、 writeFileで出力される予定のファイルをすぐに使う例が見当たりませんでした。
writeFile が遅延するとしたら、少なくともlazy IOによるものではないとおもいます。
書き込む系はlazy IOではないはずです。
バッファリングとか、ほかの問題が起きていないでしょうか?
writeFileは閉じるときにバッファを流すはずなのでファイルシステムの問題ではないでしょうか?
ありがとうございます。調べてみます。
@askjfbd has joined the channel