haskell-jp / questions #86

メンテが止まってるのはやっぱ避けた方がいいと思いますよ。
別に学習用途で使う分には全く問題ないと思いますが、真面目に長期間運用するアプリケーションに採用するのは避けた方がいいと思います。
成程了解です、ありがとうございます
実はweb開発自体をあまり経験してないので、その学習も兼ねて一通りやってみて、実際に使う時には他のものを考えます!
@koji.ishimoto has joined the channel
https://wiki.haskell.org/GHC/Type_families
の記事を読んでいて見慣れない記号が出てきました。


sumCollects :: (Collects c1, Collects c2, Elem c1 ~ Elem c2) => c1 -> c2 -> c2
sumCollects c1 c2 = foldr insert c2 (toList c1)

上記の「Elem c1」と「Elem c2」の間の「〜」は何を意味しているのでしょうか。
ちなみに、上記のElemはtype familyにより、以下のように宣言されています。

class Collects ce where
  type Elem ce
  empty  :: ce
  insert :: Elem ce -> ce -> ce
  member :: Elem ce -> ce -> Bool
  toList :: ce -> [Elem ce]

通常の型制約とは異なることを示す記号だとは推測しますが、ググってもパッとは出てこず。。
等しいことを表してたはずです(あまり自信がない)
@ncaq
回答ありがとうございます!
なるほど!確かに

sumCollects c1 c2 = foldr insert c2 (toList c1)

で、c1の要素をc2にinsertしているので、辻褄が合いそうです。
個人的な実用では
PersistEntityBackend val ~ SqlBackend

とかでPersistentのバックエンドがSQLであるとかの確認でよく見ますね
Equality Constraintsというんですね:smile:
https://downloads.haskell.org/~ghc/8.0.2/docs/html/users_guide/glasgow_exts.html#equality-constraints

@ncaq さんのおかげで検索できました!
Haskell (GHC) で記号を調べるときは Haskell Symbol Search Cheatsheet が便利です
https://github.com/takenobu-hs/haskell-symbol-search-cheatsheet
@kakkun61
ありがとうございます!
マトモな性能の疑似乱数ライブラリって現状だとmwc-randomしか選択肢ないんでしょうか?
$ ghci
GHCi, version 8.6.5:   :? for help
Prelude> let x = 123
Prelude> return (x :: Int, x :: Float)
(123,123.0)

という風にghciだと x :: Num a => a なのから (x, x) で IntFloat のタプルにできるんですが、
$ cat test.hs
test = do
  let x = 123
  return (x :: Int, x :: Float)
$ ghci
Prelude> :load "test.hs"
[1 of 1] Compiling Main             ( test.hs, interpreted )

test.hs:3:21: error:
    • Couldn't match expected type 'Float' with actual type 'Int'
    • In the expression: x :: Float
      In the first argument of 'return', namely '(x :: Int, x :: Float)'
      In a stmt of a 'do' block: return (x :: Int, x :: Float)
  |
3 |   return (x :: Int, x :: Float)
  |                     ^
Failed, no modules loaded.
Prelude> :set
options currently set: none.
base language is: Haskell2010
with the following modifiers:
  -XNoDatatypeContexts
  -XNondecreasingIndentation
GHCi-specific dynamic flag settings:
other dynamic, non-language, flag settings:
  -fexternal-dynamic-refs
  -fignore-optim-changes
  -fignore-hpc-changes
  -fimplicit-import-qualified
warning settings:
Prelude>

ってなるのなんででしょう?
test :: IO (Int,Double)
test = do
  let { x :: Num a => a ; x = 1 }
  let y = (x,x) :: (Int,Double)
  return y

ならいけましたよ
私が知る限りでは、mwc-randomだけだったと思いますね...
もっと詳しい人が答えるべき泣きもしますが、以前(多分一年ぐらい前)探したときはそんな感じでした。
これも直接の回答になってなくて恐縮ですが、案の定 NoMonomorphismRestriction を有効にしたらどの場合でもエラーになりませんでしたね。
おー、ありがとうございます
@naohaq @igrep
単相性制限に引っかかるからなのか。構文についてもいつのまにか勘違いしてそう…
https://wiki.haskell.org/Monomorphism_restriction
あー、やっぱり、
The restriction is turned on by default in compiled modules, and turned off by default at the GHCi prompt (since GHC 7.8.1).
とありますね!
もう解決済みでしょうか?

ghcのperformGCはGCの完了まで待たずに、実行をブロックしないものと思っていますが

これはnon-moving GCの話でしょうか?あとで時間があるときにコードを見てみようと思うのですが、デフォルトのGCはSTWなのでブロックすると思います。
ありがとうございます。
まだ解決してなかったです。
ちょっとわかったのはFFIの場合はcのfinalizerはGC中に、haskellのfinalizerだとGCとは別のスレッドで実行されるのですね。
http://blog.ezyang.com/2014/05/the-cost-of-weak-pointers-and-finalizers-in-ghc/
それなのでブロックしてないように見えていたというのはありました。
performGC->scheduleDoGC->GarbageCollect
doIdleGCWork->runSomeFinalizers->runCFinalizers
と呼ばれていますが、cのファイナライザを呼んでいるのはscheduleDoGCのdoIdleGCWorkですかね。
GarbageCollectの前後で呼んでいますね。
performGCを一回呼ぶだけだとすぐにcのファイナライザは呼ばれなかったりしますか?
https://gitlab.haskell.org/ghc/ghc/-/blob/master/rts/Schedule.c#L1844-1862
ありがとうございます。mersenne-random-pure64 を使ったら異常に遅くてなんなんだこれ、と思っていたんですが、紹介していただいた記事( https://alexey.kuleshevi.ch/blog/2019/12/21/random-benchmarks/ )を読んだ限りだと、
As it turns out, `randomR` and consequently `random` are oblivious to the concrete type that they are generating and all of the integral numbers go through the arbitrary precision `Integer` in order to produce the value in a desired range.
System.RandomrandomR を使うと乱数生成器のアルゴリズムに関係なくパフォーマンスが激しく落ちるということなんですかね。
random は次バージョンで改善されるそうです
https://github.com/haskell/random/pull/61#issuecomment-633002711
Cファイナライザはmajor GCとidle GCのタイミングで実行されます。

https://gitlab.haskell.org/ghc/ghc/-/blob/87102928cce33d9029ca4cc449dde6efc802b8ec/rts/Weak.c#L183-212
ここら辺の解説を読むとCファイナライザを呼ぶときに停止時間を短くするため、あらかじめ決められた数のファイナライザ(100個 https://gitlab.haskell.org/ghc/ghc/-/blob/87102928cce33d9029ca4cc449dde6efc802b8ec/rts/Weak.c#L218)を実行した時点で残りのファイナライザは次回のidle GCが呼ばれるまで遅延するようです。

runSomeFinalizersの引数allがtrueの場合はすべてのファイナライザを実行しますが、これはmajor GCが呼ばれるかRTSがexitするタイミングで呼ばれます。
従ってmajor GCを2回走らせてみてオブジェクトが解放されるか確認してみるといいかもしれません。
https://gitlab.haskell.org/ghc/ghc/issues/18239 ちなみに元のissueがcloseされているのは何故でしょうか?
従ってmajor GCを2回走らせてみてオブジェクトが解放されるか確認してみるといいかもしれません。
よく読むとmajor/minor関係なくdoIdleGCWorkは呼ばれますね。minor GCだけでも良さそうです。ただ元のissueではcopying GCでは問題が起きていないように読めるのですが、doIdleGCWorkはcopying/non-moving関係なく呼ばれているので別の問題かもしれません。
https://gitlab.haskell.org/ghc/ghc/-/merge_requests/3389
こっちがあるからクローズですかね
元のissueがmasterで直ってから閉じた方がいいと思います。特にGHC開発者は人手が少なくて忙しそうなので、closeされると問題が見落とされてしまいそう。
リンクありがとうございます
copying gcだと問題おきなかったのですが
簡単なケースだと問題が再現できなかったのでどう攻めたものかと悩んでます
https://github.com/junjihashimoto/gc-test/blob/master/Main.hs#L34
ここで一回よぶか二回よぶかで結果が変わってきますね。
@yskbsk13 has joined the channel
benzene.chlorobenzene
@benzene.chlorobenzene has joined the channel
nonmoving gcだとprofileとれないですね。だれかebpfでprofileとった例とかあるといいのですが。
funccountでperformGCいれてもでてこないですね。たぶん使い方が間違っているのだと思いますが。
relational record でプレースホールダーが ? じゃなくて $1, $2 になるオプションってありましたっけ?
少なくとも私がいじってた頃はなかったですね...
SQL標準じゃないから、でしたっけ? @khibino
? が SQL 標準かどうかは把握していないんですが、
おおくの RDBMs ドライバがこの機能をサポートしているのでそうしています。

PostgreSQL や MySQL だと、どちらも使えたりするんだろうか。
Lensについて質問です
over の第二引数には a -> b な関数をとると思うのですが、ここで a -> m b (具体的には a -> IO b )をとる関数というのは存在するのでしょうか
Hoogleでもうまく検索できず…
over myLens <$> (ioAction) <*> data

という形でできないかなぁと思ったのですが、 ioAction はこの段階で評価されないのでできないよな…というところまで行きついて詰まりました
実はLensそのものがそうなってるんですよ(実は全く同じ質問を随分前にここでして教わりました :sweat_smile:
over だと Asetter を使っていて Identify に包まれている、ってとこをみたのですがそれと同じですか…?
:point_down: の定義のとおり、
その`Identity` を Functor f => fに一般化したのが Lens そのものなので、
myLens ioAction data でコンパイル通りませんか?
type Lens s t a b = forall f. Functor f => (a -> f b) -> s -> f t 
標準の状態だと PostgreSQL の拡張問合せプロトコルだと $n だけみたいですね(設定で変えられるのかな

use $1, $2, etc.
https://www.postgresql.org/docs/12/sql-prepare.html
“etc.” とは
あ、なるほど!!
試してみます!
過去自分で質問した時の記録を探していて気づいたのですが、 https://haskell.jp/slack-log/html/C5666B6BB/72.html#message-1570939612.018800 といいよく私と同じ問題にハマりますね... :sweat_smile:
この、containersパッケージの State の定義がおかしい問題も以前私も random で話題にしたことがありまして...
$3, $4, $5, ... のことを指しているのでは
.etc
HDBC コンパチにするために ? 形式から $ 形式に変換する実装があったのを思い出したので切り出した
http://hackage.haskell.org/package/postgresql-placeholder-converter