haskell-jp / questions #20

@umezuryuplus has joined the channel
@yosikawa has joined the channel
syslog使ってます
fusion の質問です。Bird の本に頻出する型 f . foldr g a = foldr h b [PoFAD] (pp.34) が良く分かりません。何かもっと詳しい説明・文献がありますでしょうか?
他の型であれば、例えば "foldr/build fusion" や "destroy/unfoldr fusion" や "Church/Cochurch fusion" ならば以下の文献がありますが、これらとも違いますよね?
[PoFAD] (2010) "Pearls of Funcional Algorithm Design" Bird, R
[FPCA 1993] "A Short Cut to Deforestation" Gill, A. Launchbury, J. Jones, S.L.P.
[ICFP 2002] "Shortcut Fusion for Accumulating Parameters & Zip-like Functions" Svenningsson, J.
[Oxford 2011] "Theory and Practice of Fusion," Hinze, R. Harper, James, D.W.H.
hsyslogのことですか?
そうです。
特に理由はありませんが、成り行きでhsyslogを直接使う場合と monad-logger-syslogから使う場合があります。
optparse-applicativeに関する質問です。サブコマンドで定義したhelp文を`--help`コマンドで表示させる方法はあるのでしょうか。以下のようなコマンドを受け付けることを期待しています

:main processTicket --help


コードをGistに掲載しました。
https://gist.github.com/HirotoShioi/e88f3d1622d7d7961e906191263d3d31#file-optparse-applicative-L24
普通に helper が使えたはず
command "collectEmails" (info (pure CollectEmails <**> helper)
            (progDesc "Collect emails requested by single user"))
できた。。!ありがとうございます!
Hutton の “A tutorial on the universality and expressiveness of fold” http://www.cs.nott.ac.uk/~pszgmh/fold.pdf の “3.2 The fusion property of fold” にも解説があります。
Wadler の “Theorems for free!” https://people.mpi-sws.org/~dreyer/tor/papers/wadler.pdf に Theorems for free の応用として “Figure 1: Examples of Theorems from type” にも解説なしで (後から訂正:「3.2 Fold」に)出てきます。
subparserの代わりにhsubparserっていうそれに特化したようなのがあったかと思います(今手元で調べられる状況じゃなくて恐縮ですが)。
ありました!
ありがとうございました 特に前者は参考になりました
全く見当違いかもしれませんが、Cardano-SLはkatipを使いたいとか言ってました。
https://hackage.haskell.org/package/katip
Running a program which logs 500k times a simple message using both katip and log-warper showed that katip is much faster and uses less memory than log-warper.
64bitの符号なし整数を、次のような形式のJSONで送ってくる(私が直接いじれない)サーバーがあります。
{ high: <上位32bitを表す符号付き整数>, low: <下位32bitを表す符号付き整数> }

この形式のJSONから Int64 を作り出す方法を考えているのですが、バイナリ力が低くて悩んでおります。
上位ビットは shiftL 32 とすればいいのはすぐにわかったですが、下位ビットについてどうすればいいか、教えていただきたいです。
例:
input: { high: 177247787, low: -813694976 }
output: 761273451934646272
このサーバーおかしいだろう。。。
if low
0 then low else ((low :: Int64) + 2 ^ 32)
Word32にキャストできたような
そう、今同僚と話してたら気づきました。
fromIntegral (negate 813694976) :: Word32
このサーバーおかしいだろう。。。

JSの仕様上64bit整数を直接表現できない故の苦渋の策なんでしょうね。。。
Prelude Data.Int
(-1 :: Word)

<interactive>:3:3: warning: [-Woverflowed-literals]
Literal -1 is out of the Word range 0..18446744073709551615
18446744073709551615

=。=Warningが出るけど
下位はWord32にキャストしてからInt64にキャスト、 shiftL 32 した上位と足し算、で大丈夫…ですよね?多分
はい、リテラルでやると警告が出ますが明示的に fromIntegral する分には問題ないはずです。
Hmmm,Cの強制coercionが欲しい(
そもそもやはりこのサーバーがおかしいと思う=。=
177247787 `shiftL` 32 + (fromIntegral (fromIntegral (negate 813694976) :: Word32) :: Word64)
まあ、「JSの仕様上64bit整数を直接表現できない故の苦渋の策」でしょうねぇ
え???そうなの?
JavaScriptは浮動小数点数しかございませんので
JSの数値リテラルは全部doubleとして処理されてしまうのです。。。 :disappointed_relieved:
整数は(倍精度浮動小数点の仮数部である)53bitまでしか使えません
http://blog.tmyt.jp/entry/20101201/1291166929
よってこういうことが起こる
これはさすが。。。
なので、高速化のためにJITコンパイラが「こいつはループカウンタとしてしか使われていないから整数に置き換えてもいいな」みたいな推論をしてやる必要があったりします。そういう涙ぐましい努力の結果JavaScriptのあのスピードがあるという感じだそうです
上記の回答でできたっぽいですが fromIntegral 2回使っているところが非常に醜いので TypeApplications を使ってみました。
177247787 `shiftL` 32 + (fromIntegral @Word64 (fromIntegral @Word32 (negate 813694976)))
:face_with_monocle:@ とはなに?
TypeApplicationsは、
idconst, 今回の fromIntegral のような多相関数を、「どの型に対する関数にするか」を @<型名> で明示できるようにしてくれます。

例えば ida -> a という型ですが、 id @Int のように @Int を明示することで、 Int -> Int として処理させることができます。

GHCiで試すと :point_down: のようになります。
> :set -XTypeApplications
> :t id
id :: a -> a
> :t id @Int
id @Int :: Int -> Int
すみません、 TypeApplications を使った方法、間違いでした(最初の方でうまくいったように見えた理由がいまいちわかりませんが)。正しくは :point_down: です。
177247787 `shiftL` 32 + (fromIntegral @Word32 @Word64 (fromIntegral @Int32 @Word32 (negate 813694976)))

却って冗長になってしまいましたね。。。 :disappointed:
私の回答はこれです shiftL 177247787 32 .|. 0xffffffff .&. (-813694976)
確かに。足し算しなくても .|. でいいのか。
なるほど。よく考えたら元はJSONなんだから Integer として処理してしまったもいいんですね。
.|.+ ってどっちが「善」なんでしょうかね(ill-definedな問)
今回の場合 .|. の方が理にかなっていると思いますよ + の場合桁上がりを考慮しないといけない分わずかに処理が遅くなる可能性もありますが、今回のような計算の場合、起こりえないことがあらかじめわかっていますし。
CPUのサイクル数はほとんど同じのはずですが、ビット演算の文脈なので.|.の方がいいと思います(なおxorも可といえば可)
大きな整数はStringで返ってくるような仕様もあるようです(サーバーは変えられないとの事ですが、正しい仕様は何かという議論について参考までに) https://github.com/syucream/hastodon/issues/9
64bitの符号なし整数をInt64では1bitたりない気がします。
64bitの符号あり整数ならいいでしょうが。
64bitの符号なし整数はInt64でなくてWord64をつかうのですね。