haskell-jp / questions #69

あともう一つのアプローチとして、Alexが返す例外をパーサーコンビネーターなどでパースしてしまう、というやや遠回しな手もあるかと思います :sweat:
お疲れ様です
nixを使ったhaskell のベストな開発フローが知りたいです
cabal v1 or v2
どちらがお勧めでしょうか
エディタはホストのものをつかうのがいいですか
それともnixのなかに入れ込むのがいいのでしょうか
あとnixによるいいci環境があれば合わせてお願いします
これの招待リンクってどこかにありますか?
最初のメッセージのリンクが招待リンクのはずですが...
GHCでも使われてるし字句解析と構文解析が別れるからわかりやすいのかなーと思った次第です。エラーメッセージのパースは考えましたが本末転倒すぎるので見なかったことにします……
パーサのエラー出力って割とホットな問題なんですよね。GHCですらパースエラーについては、最初の一個をぶん投げて終わり、にしてる奴なので。
なので妥協するか、または良いアプローチを自力で探ってみるかの2択かと思います
招待リンクは
bit.ly/2GwPFrs
でした
Safe/Trustworthy プラグマに関する質問です。
ある時点で、importしているモジュールがTrustworthyであったために、そのモジュールも Trustworthy にしていたとします。
importしているモジュールがパージョンアップして、Safe に変わりました。
すると、
'XXX' is marked as Trustworthy but has been inferred as safe!
みたいな警告が出るようになります。
この警告を消すスマートな方法はありますか?
プラグマ部分に #ifdef って有効なんですかね?
なるほど……ありがとうございます。とりあえずMegaparsecあたりを触ってみて、それでもしっくりこないようなら言語仕様に沿ったパーサを自前で書く、といった方向で試してみます
https://github.com/ekmett/lens/blob/60b89993903af95f138411a0721e952e84047a6c/src/Control/Lens/Internal/Setter.hs#L4 のように、Trustworthyを切り替えるのはしばしば見られます。あるいは-Wno-trustworthy-safeで無視するのもありだと思います
ベストプラクティスかはわからないけど、自分が関わっているプロジェクトの開発環境はこうなっているという回答でもいいかな。。?
megaparsec で簡単な言語をパースする例としては、ぼくにはこれがわかりやすかったです https://markkarpov.com/megaparsec/parsing-simple-imperative-language.html
ありがとうございます!読んでみます
う・・でも改めて見たら冒頭に「The text here may be obsolete. See this tutorial instead.」とありました。
さっきのはバージョンやらスタイルやらが古いかもしれません。こちらのほうが網羅的でよいようです。長いですが…。
大丈夫です
お願いします
megaparsecで書いたパーサーがeofで止まらず無をパースしようとして死ぬんですが、助けてください
https://github.com/1inguini/mud/blob/detailedAST/src/Parse.hs
詳細ぱっとわかりませんが、 many には本当に慎重になった方がいいです。
思い出した。普通のパーサコンビネータだと左再帰がうまく書けそうにないような気がしたのでAlex+Happyで自動生成にしたんでした。やりたいことは x y z を右結合の指定なしに Apply (Apply x y) z という構文木にしたいのです。そのへんHappyがうまくやってくれます
Elmが(Idrisもらしい)Happy使わずパーサコンビネータだけであの文法をパースしてるのを見るとできないこともなさそうなんですが……
たしかに many のどれかを some にしたら急に動いたりするかもしれないですね。
左再帰とかもろもろの演算子のあれこれを、演算子の結合と優先順位を指定するだけでどうにかしてくれる makeExprParser という関数がparser-combinatorsというパッケージにありまして :smirk:
http://hackage.haskell.org/package/parser-combinators-1.2.0/docs/Control-Monad-Combinators-Expr.html#v:makeExprParser
『右結合の指定なしに』
お、ifdef が効くのですね。ありがとうございます!
ちょうどそこに行き着いたところでした!
(一旦諦めました)
(全然関係ないけど、GitHub 上のコードを貼るときはコミットハッシュ込みの方がいいよ(あとでみた時に変わってしまう))
あと、出だしがよくわからないや
例えば、ghci でこういう風に実行したら止まらない(理想はこう)とかを書いてくれると実装を追いやすいです。
nixを使ったhaskell のベストな開発フローが知りたいです
> cabal v1 or v2どちらがお勧めでしょうか
v2ってnew-* がついてるコマンド郡のことですよね。。?その場合であればv2を使用しています


> エディタはホストのものをつかうのがいいですか、それともnixのなかに入れ込むのがいいのでしょうか (edited)
ホストのものを使ってます。nix-buildを使ってnix環境に入り込みつつ、既存のエディタにもアクセスできるようにしてます。


> あとnixによるいいci環境があれば合わせてお願いします

弊社ではhydraを使ってます
BuildKiteも使ってるけど、これはArtifactの生成だけに使ってるっぽくて、ビルドができるかどうかしかチェックしてないです。
ありがとうございます。

技術的なところがよくわかってなくてすみません。
cabal v1 or v2のところでnixでhaskellのパッケージをインストールした場合でもv2でインストールしたパッケージを
利用できますか?

OSSでhydra使うにはどうしたらいいでしょうか。自分でたてるしかないですか?
esqueletoでwhere句を作れずに困っています。makeWhereでwhere句を返したいのですが、個々の検索条件式は良いのですが、E.&&.でまとめて返したいのですがどのように記述すれば良いか困っています。よろしくお願いします。
まだ公開の準備が整ってないコードなので断片的ですし的外れかもしれませんが私はこのように`fordr`で検索条件をくっつけていました
Nothingの場合適当にTrueでも埋め込んでおけば良いかと
ありがとうございます。 Nothing側にE.val Trueを入れてやってみたら、今回の主旨とは違うコンパイルエラーが出たのでちょっとそちら側を処理してからまた報告します。

• Couldn't match type ‘Text’ with ‘Maybe Text’
arising from a use of ‘ClientCompany’
ありがとうございます。where句きちんと作成できました!
コンパイルエラーで多少型合わせの調整しましたが、なんとかなりました。
https://github.com/haskell-jp/blog/issues/167
こちらの件で、「Strictを指定していようといまいとStackOverflowを起こす」という実験のために、GHCのRTSのスタックサイズを減らすよう -K1k と指定してみたのですが、うまくStackOverflowを起こすことができません。
どこで間違ったのか、教えてください!

ソースコード: https://github.com/haskell-jp/blog/blob/8c1db1af41df8eca8753bb9bcee38691ad13988c/examples/strict-gotchas/stackoverflow.hs
コンパイル時のコマンド:
stack exec ghc -- -O0 -rtsopts -with-rtsopts=-K1k .\stackoverflow.hs
-XStrict をつけたら溢れた。 :thinking_face:
なお、GHCのバージョンは8.6.5です。
コマンドにバックスラッシュが混ざっていることから察せられるとおり、Windows版を使っています。
単項マイナスを括弧で囲むとパースできなくなってしまいます(囲まなければちゃんとパースできる)
https://github.com/1inguini/mud/commit/3bce80c19ea34ce74fec88eac34c765f1def1d70
❯❯❯ stack run parse '(-12)'

<stdin>:2:2:
  |
2 | (-12)
  |  ^
unexpected '-'
expecting '"', ''', '(', ')', ':', '[', digit, or integer
(1) そのコミット以前はできていたんですか?それともこのコミットは関係がない?
(2) 念のため確認ですがパーサーの全体像は https://github.com/1inguini/mud/blob/3bce80c19ea34ce74fec88eac34c765f1def1d70/src/Parse.hs ということですよね?
(1)git checkoutして試したらできました
(2)言ってることがよくわかりませんが、そのリポジトリかと言われればそうですが、ブランチはparser_from_scratchです
あとeofで死ぬ問題は解決しました
パーサを書き直してsepByをsepEndByにしたらなんか動きました(もとのパーサのsepByを置き換えても別に直りませんでしたが)
anonFunsが悪さしていました