haskell-jp / questions #79

そうですね。正確には、 [e| |] のなかで束縛されてない変数が自動で unboundVarE $ mkName "e" されるところが、です。
うーんと,検討外れの答えをしていたらすいません.QuasiQuote の中の式は,
1. パース時そのまま一緒に Haskell の式として解析され Ast になります.
2. で,そのままリネームされます.
3. その時に,値の変数は,スコープ内にない変数は unboundVarE 相当に,スコープ内に変数がある場合はそのままその変数に解決され varE 相当で解決されます.
QuasiQuote はあまりドキュメントがないですが,基本的に変数の解決の挙動は, Language.Haskell.TH.lookupValueName に合わせてありますね 通常のHaskell 式としてのスコープ解決に合わせてあるが正解ですね.なので, lookupValueName とは異なる挙動になるのですね
訂正はどっちかというと lookupValueName の挙動を僕が誤解してたからなんですが、 QuasiQuote の挙動の方は個人的には割と自然な挙動だと思っていて、quote を書いたところで解決できる変数が解決されず、splice 時まで遅延されるのはむしろ特殊な挙動な気がします
quote を書いたところで解決できる変数が解決されず、splice 時まで遅延されるのはむしろ特殊な挙動
ん?それって [e| |] の挙動では?
話をドキュメントの話に戻しますが、これが件の挙動についての記述かなぁ。
https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#extension-TemplateHaskellQuotes
Local names, which are not in scope at splice locations, are actually evaluated when the quotation is processed.
なんか "splice" と "quotation" という用語の使い方が違う気がしますが...
すみません、やっぱ違うっぽいですね...
splice と言うのは TH 式を実際に Haskell の式に展開するフェーズのことで、quote を TH 式に展開するフェーズとは異なることに注意です
thE = [e|v|]
f v = $(thE)
において、thE の値を計算するのが quotation processing / f の式を計算するのが splice です
lookupValueName は splice 時に与えられた名前を解決し、quote 中の変数は quote processing 時に名前を解決します
あっ、もしかしてquoteの中の束縛されてない変数の話じゃなくてquoteの中で見える変数の話、ということですか?
それなら納得です。
ここまでの話は,`v` が見えない状況で [e|v|]unboundVarE $ mkName "v" 相当になるのは何故かという説明のつもりでしたが,元の質問は
>>> :set -XTemplateHaskell
>>> import 
>>> let e = () in $(unboundVarE $ mkName "e")
()

の挙動がなぜこうなってるのか単純に分からないということですか?
正確には、 [e| |] のなかで束縛されてない変数が自動で unboundVarE $ mkName “e” されるところが、です。
の文面がどういうことを言いたいのかいまいち分かってないです
ここまでの話は、splice においてTH 式の内容を Haskell の式に設置させる時にどう名前解決されるかの話はしていなくて、lookupValueName の話も含め TH 式の Name がどう解決されるかの話をしています
ここまでの話は,`v` が見えない状況で [e|v|]unboundVarE $ mkName "v" 相当になるのは何故かという説明のつもりでしたが
はい、その認識で合っています。

そしてようやく気づきましたが
lookupValueName は splice 時に与えられた名前を解決し、quote 中の変数は quote processing 時に名前を解決します
どうやらここがわかっていないようです。
念のため確認ですがここでいう「quote 中の変数」とは`[e|v|]` における v ですよね?
quote processingが(`v`が [e|v|] の外には定義されてない状態で) [e|v|] を`unboundVarE $ mkName "v"` に変換するという意味ならば、`v`は定義されてないのですし、「quote processing 時に名前を解決」できず、結局spliceするときに解決することになるのでは?
quote processing での名前解決と言ってるのは,正確には変数が quote processing 時に解決できるならその名前 n で varE n に,それ以外の時は unboundVarE n にするということを言っています.で, unboundVarE n の splice 時の解決方法に,quote で書かれた変数かということは関係ありません.
unboundVarE n は,unresolved identifier を表すということになっていますが,正確には identifier expected to be resolved というニュアンスが正しく, splice 時のリネーム時に通常のリネームと同じように (元々の Haskell プログラムも最初変数部分は全て unboundVarE で構成され,リネーム時に varE に解決されます) 解決されるため,
>>> let e = () in $(unboundVarE $ mkName "e")
()

という挙動になります
@smalltalker74 has joined the channel
@omura.cre has joined the channel
@t.takeuchi.a has joined the channel
@t-mishima has joined the channel
@uhryks has joined the channel
@taku2011katagiri has joined the channel
@ozaki.ryushi has joined the channel
@yohta.kimura has joined the channel
@p.y.on1.3 has joined the channel
モジュール名の決定についての質問です
ライブラリ内のモジュール名を決めるとき、特に一番上のモジュール(`Data`とか`Control`とか)を決めるときに則った方が良いルールなどあるのでしょうか
具体的には、今分散型SNSであるMisskeyのAPI用ライブラリを書いているのですが、これは`Network`以下か`Web`以下かどちらが適切なのでしょうか…
(とりあえず`Network.Misskey`にしているのですが、Hastodonが`Web.Hastodon`であることに気づいて気になった次第です)
どちらでも良いのなら今のままにしようと思っています
私が知る限り、決まりなくみんなめいめいにやってる感じですね。。。
ただ今回に限っていえば、いわゆるWeb APIのクライアントは Web を使う傾向があるようなので私は Web の方がいいと思います。
例:
http://hackage.haskell.org/package/slack-web
http://hackage.haskell.org/package/twitter-types
成程ありがとうございます!
Webに変えておきます
Haskell での mealy machine (`newtype Mealy a b = Mealy { runMealy :: a -> (b, Mealy a b) }`) ですが、これをモナドにする方法って何かあるでしょうか?
ArrowMonad を使えるが、その場合では a が () になってしまうので問題がある
• Free Monad 系もあるが、それ以外で何かがないか
無限ストリーム的な構造をモナドにする方法として対角化が考えられます。例えば[1,2,3..]を出力する機械にkをバインドすると、k 0の0番目、k 1の1番目、k 2の2番目の要素を採取していくような操作です。ムーアマシンでは実装できることが知られていますが(cf. http://hackage.haskell.org/package/machines-0.7/docs/src/Data.Machine.Moore.html#line-100)、ミーリマシンについてはわかりません
んー、なるほど、そのまま扱わず streaming 系に変換するのが現実的ですかね
a ~ () で定義できるならReaderTと合成すれば一般に行けそうな感じがします
pure x = Mealy $ \_ -> (x, pure x)
Mealy p >>= fq = Mealy $ \x -> let {(y, p') = p x; (z, q') = runMealy (fq y) x} in (z, p' >>= q')

だとどうだろう
あと、YampaのSFがMealy machineで、`switch` https://hackage.haskell.org/package/Yampa-0.13.1/docs/FRP-Yampa-Switches.html#v:switch を継続モナド Cont で書くとモナドチェインが出来て嬉しい、という話もあります
@s.okuda.0728 has joined the channel
Yampa のやつの話はモナドとして Cont (Mealy a b) を使った方がいいみたいな感じですかね。 a -> Mealy a b の newtype ならモナドになれるかですが、モナド則を満たせずになれなさそうな気がします。
プロファイリングをしようとして,
ghc-options:
- -rtsopts
- -prof
- -fprof-auto

を指定したら,
ghc: panic! (the 'impossible' happened)
  (GHC version 8.6.5 for x86_64-unknown-linux):
	lookupGlobal
  Failed to load interface for 'GHC.Integer.Type'
  Perhaps you haven't installed the "p_dyn" libraries for package 'integer-gmp'?
  Use -v to see a list of the files searched for.
  Call stack:
      CallStack (from HasCallStack):
        callStackDoc, called at compiler/utils/Outputable.hs:1160:37 in ghc:Outputable
        pprPanic, called at compiler/typecheck/TcEnv.hs:132:32 in ghc:TcEnv

Please report this as a GHC bug:  

最小の再現状況を作ろうと思うのですが,この場合どこから手をつけるのがいいでしょうか.
are you using cabal? then you shouldn't pass -prof directly in the ghc-options but use --enable-profiling
I'm using stack. how can i use 'stack build' ?
stack build --profile
ありがとうございます.Thank you.
うまくビルドできました.
失礼、上の奴はだいぶボケてました。

ArrowMonad Mealy のMonadインスタンスは、 MealyArrowApply インスタンスから導出されるので、
問題はMealyがArrowApplyになるかどうかです。

とりあえず型合わせで app を定義してみます。

app = Mealy $ \(f, x) -> let (y, g) = f x in (y, ???)

???に合う型の変数にはfまたはgがあるのですが、

• fを選ぶと、内部状態が毎回リセットされてしまう。
• gを選ぶと、2回目以降の入力値fが捨てられてしまうため、fが変化しても追従しない
と、いずれも問題があります。
これは単に直観的な問題だけではなく、実際にArrowApplyのlawどれかを満たさないはずです https://hackage.haskell.org/package/base-4.12.0.0/docs/Control-Arrow.html#t:ArrowApply
Yampaのやつは、Contはあまり本質じゃなくて

newtype Switch a b c = Switch (Mealy a (b, Maybe c))
と置いてやると、「cがJustの時だけ内部状態をリセットしてやる事で、必要に応じた動作ができる」というのがやりたい事でした
haskellとかの関数型言語の計算量ってどうやって求めればいいんでしょうか?
手元の「関数プログラミング入門」という本では、漸化式を立ててそれを解いているようです。検索してみたところ似たような内容の記事がありました。
ただしそれは先行評価での場合で、「遅延評価の下では簡約ステップ数を数えるのが難しく、いまだ研究対象だ」とあります。
https://www.cs.cmu.edu/~rwh/theses/okasaki.pdf
とかにそこらへんが書いてありそう…。(↑の本に参考文献の1つとして書いてありました)
余談ですけど、関数プログラミング入門の改訂版が「Haskellによる関数プログラミングの思考法」 です、確か。
https://asciidwango.jp/post/157185312025/haskellによる関数プログラミングの思考法

で、Haskell じゃなくて遅延評価の言語ではって言う話であれば「珠玉のアルゴリズムデザイン」とか「純粋関数型データ構造」って書籍に結構書いてあるはず(全部訳書)
なるほど、 Yampa のやつは引数の方が大事だったわけですか。まだよくわかってませんが……
https://www.stackage.org/haddock/lts-15.1/machines-0.7/Data-Machine-Mealy.html のように Mealy は ArrowApply のインスタンスになっています。