haskell-jp / questions #8

mingw32_HOST_OS が定義されていたら、 winsock2.h は存在すると仮定してもいいですか? (network パッケージ、過去の遺産が降り積もっていて、泣きそうです。)
networkパッケージてC部分のコンパイル時にconfigureしてませんでしたっけ?ヘッダ(や,その他ライブラリ等)の存在確認がしたいならAC_CHECK_HEADERSとか使えば実際にconfigure時に確認してマクロをdefineできるんじゃないですか?
Array# …でしょうか。
https://hackage.haskell.org/package/ghc-prim-0.5.1.0/docs/GHC-Prim.html#t:Array-35-
どうやってByteStringに変換したら良いのかわからなくて詰まってしまいましたorz
FFI には
- UNIX 用の ccall
- Win32 用の stdcall
が定義してあるんですが、Win64用にはないんですよ。
で、GHC はWin64上では ccall/stdcallどちらを指定しても、Win64用のABIを使うようです。しかし、stdcallを指定しいると、警告が出てうるさいです。
なので、Win32だとstdcall、Win64だとccallにしたかったのでした。
一つ、stdcallの警告が残っているけど、それは取れます。あとは、Haskell的な警告をなくすだけ。
現在、どちらのマクロも使えるんですが、使い分けの基準が分かりません。同じ意味なら、どちらかに統一したいのです。
どちらのって何と何ですか?
mingw32_HOST_OSwinsock2.h が存在するときに定義される HAVE_WINSOCK2_H です。
mingw32_HOST_OS であっても,includeパスがおかしいとかでconfigure時に見えてないような事態も考えられるので winsock2.h のincludeでは HAVE_WINSOCK2_H も見るようにしたほうがいいです.どちらかに統一というか #ifdef mingw32_HOST_OS#ifdef HAVE_WINSOCK2_H#include <winsock2.h>のように包含関係になるような感じじゃないかと
Data.Array.Base を読み込むと UArray Int Bool に対して ByteArray# を取り出せるので、後はなんとかなりませんかね?
ありがとうございます!
ByteArray# について調べてる途中で UArray がByteArrayAccessのインスタンスになってることに気づいて convert を使えば思ってたことができそうです :bow: 詳しい実装もコードを読んで勉強してみます :pray:
https://hackage.haskell.org/package/memory-0.14.10/docs/Data-ByteArray.html#v:convert
Windows で winsock2.h が見えないときは、どのみちエラーにすべきなので、`mingw32_HOST_OS` だけでよくないですかね?
ああ、`convert` 使ってもいいなら、それが便利ですね。
UArray Int Bool が、本当にビット列をパックしているかは、確かめてください。
エラーの発報の観点から話をするなら,理想的には判明時点で早々に発報すべきです.その最速判明タイミングとはconfigure時点であり, AC_CHECK_HEADERSaction-if-not-found ケースでエラーにすることもできます.
なるほど。
早期発見の努力はするとして、コードの方は、どっちかに統一してもいいですよね?
そちらは統一していない意図がわからないの恐らく…としか言えないですね.
ええ、デッドコードです。今まで誰も手につけられなかったのです。僕がやらなければ、今後誰もやらないでしょう。
@igrep set the channel topic: お悩み相談専用チャンネル。回答は原則スレッド機能でやりましょう。複数の質問を同時に投稿しやすくするための配慮です。過去の質問は https://slacknowledge.pig-brewing.com/ から。
@igrep set the channel topic: お悩み相談専用チャンネル。回答は原則スレッド機能でやりましょう。複数の質問を同時に投稿しやすくするための配慮です。過去に :memo: された質問は https://slacknowledge.pig-brewing.com/ から。
Lazy I/O の readFile について resource exhausted (Too many open files) という例外を再現しようとして,

main = readFile "file_list.txt" >>= mapM_ (readFile >=> print . length) . lines


というプログラムを書いて ghc-8.2.2 でコンパイルし実行してみたのですが,再現できませんでした.file_list.txt には10万個のファイル名が書いてあり,カレントディレクトリにその10万個のファイルがあります.どうすれば再現できるのでしょうか?.なにか勘違いしている可能性があります.指摘していただければ幸いです.
推測ですが、 length だと全部読んで(そして自動で閉めて)しまいそうですし、 take 1 とかしてみるのはいかがでしょうか?
take 1 でも問題なく実行できるようです。
ulimit でファイルディスクリプタ数の限界( -n オプション)を小さく設定した上で, take 1 で実行してみてください.
なるほど、ulimit -n 32 とすると再現できました。ありがとうございます。
デフォルトではファイルディスクリプタの上限が 1048576 になっていました。
昔(Linuxカーネルが2.4とかの頃)はファイルディスクリプタの変化を待つシステムコールがselectしかなかったので、上限も自ずと1024くらいの小さい値だったのが、今はepollとかがあるので大量のファイルディスクリプタが扱えるということですかね
駒鳥(hxf_vogel)
@駒鳥(hxf_vogel) has joined the channel
pollも思い出してあげて下さい。
上限を引き上げたのはこの子です。
また、教えて君です :slightly_smiling_face:
型シノニムを使用するとき、宣言時のアリティを満さなければならないのですが、そうなっている理由について、いまだに、よくわからないでいます。
そのような制限がないとどのようなことが起こるのでしょうか。
これのことでしょうか?
https://stackoverflow.com/questions/4922560/why-doesnt-typesynonyminstances-allow-partially-applied-type-synonyms-to-be-use

partial applyのことなら,type checkがundecidableになるので,Haskellの派生系でも許可してるものは見かけないですね
type check が undecidable になるというところが、良くわからないのです。
type synonymは一種の型関数ですから, type A a = B a a という型関数において,型クラス C :: * -> * のインスタンスとして instance C A where という定義があった時に,最終的にインスタンスを決める時に (\a -> B a a) ~ A をどうやって判定するかという問題になります.このような問題は,一般に実際に全ての値に対して返り値が一致しているかという方法で判断しますが,これをチェックするのは通常難しいですね.

例に出したものだと単純なので決定的にできるかもしれませんが,上のstack overflowの例でこの問題を考えてみた場合,納得がいくと思います
すみません。「最終的にインスタンスを決める時に (\a a -> B a a) ~ A をどうやって判定するかという問題になります」の部分がよく判からないでいます。
例えば, type A2 a = B a a というのがあった時に, A2 ~ A なので C A2 という制約は instance C A から成り立つはずです.これをどう判定するかということですね
s/ \a a -> B a a / \a -> B a a / でした
A2 ~ A が判定できないということですか?
まあ一般にはその判定( forall a :: *. A2 a ~ A a が成り立つかどうか)が undecidable だということですね.この例の場合はdecidableにするアルゴリズムがあるかもしれません(なので,今回の場合はできるかもしれません)が,これを一般の場合で考えた場合(例えば,ブール論理を埋め込んだstack overflowの例の場合),それを判定する決定的なアルゴリズムを構築するのが困難だということです
stack overflow の例でいうと、Not True ~ False を示すのが困難ということになりますか。
ううむ。外延的に決定するしかないとすれば、そうなのかな。
あまりパッといい文献を出せませんが,もし気になるならeta expansion problemsなどで調べてみると,いいかもしれません
ありがとうございます。
@bonotake uploaded a file: nix で slack をインストールしようとしてコケました and commented: nix-env -iA nixpkgs.stack とすると図のように、

Variable not in scope:
hSetBuffering :: Handle -> BufferMode -> IO a0

と出てしまいます。
結局 slack は他の手段で (nix 使わないで)インストールしてしまったのですが、上記はどうしたものかなぁと
話をちゃんと理解してませんが、シノニムの部分適用を許すと実質的に型レベルのラムダを許すことになり、高階単一化の決定不能性が問題になる、という話ではないかな、多分。
@kakkun61 commented on @bonotake’s file nix で slack をインストールしようとしてコケました: stack? slack?