haskell-jp / random #69

後で時間があったら思いつく例を何個か作って上げようと思ってるんですが、
* パーサのデバッグ
* グラフ構造の探索など、コントロールフローが複雑な関数群のデバッグ
* notogawa さんがおっしゃってるようなパフォーマンスの改善時のデバッグ
で printf デバッグをする際、trace が出ない原因の切り分けが、遅延評価だからなのかコードのバグなのか分からないのは、だいぶ辛いというのが経験則としてあります
パーサのデバッグのイケてる方法、存在するならぜひ誰かにレクチャーして欲しい……
個人的には、attoparsecでやっている限りは traceMputStrLn の代わりに使えば割とどうにかなってますね。 :thinking_face:
あとは必ずパースした結果をトレースするよう traceShowId <$> と書いたり。
(そういえば補足ですが、パーサのデバッグというのは、パーサコンビネータでのパーサのデバッグですね)
terutomo.takahashi
@terutomo.takahashi has joined the channel
@jamesbrock has joined the channel
@shin1hi has joined the channel
遅延評価云々にかかわらず、プログラミングにおける典型的なミスや勘違いによるエンバグ例とデバッグ例をストックしておくと役にたちそう。とおもって、はや幾星霜:sweat_smile:
3つの型の直和型が欲しくなったとき、新たに型を定義します?それともEither (Either a b) c ないし Either a (Either b c)なりします?
新しく型を定義しますね
新しく定義する場合、dataで作っちゃいますか? それとも type synonym を使いますか?
data で作ります
なるほど、個人的にはそれぞれありえるかなーとは思ってて、煮え切らないけどケースバイケースな気がしていたのですが、 @hexirp さんが data 一択(?)なのはどういった理由からでしょう
混乱する可能性があるので、分かりやすさのためですね
なるほど、そこになりますかね。
dataについて分かりやすいというのは私もそこだなと思います。一方で、Either や Maybe、タプルは多くのライブラリでも視野に入ってて結構使えるライブラリが存在するのでそこはメリットかなと思っています。
で、今ちょっと微妙な気になっているのが type synonym です。
重要な抽象化であれば、type class を用いればいいのでは。
重要な抽象化だとアドホック多相になりますか?
object oriented 型の polymorphism かと問われると:question:となります。
どういう意味でしょう?
アドホック多相とはそういう意味(Java にみられるような、overload の形の多相(polymorphism) )ではないのでしょうか。
話を戻すと type synonym は割と軽いのでよく使ってたのですが、型構成子がオリジナルのものが使える(RWH流)といいつつ、逆に言えば上のようなEitherの場合Left/Rightが入れ子になるので読みづらくない?という話がありまして。
これはまぁ専用のコンストラクタを用意してもいいのですが、今度はパターンマッチでバラす方でやっぱりLeft/Rightが入れ子になるので抽象の壁破れてるじゃんみたいな気になってしまいまして。
これ型シノニムって微妙なのか?と思って質問投げてみた次第。
type synonym って
type Hoge a b c = Either (Either a b) c

みたいなイメージですか?
そっか、型クラスはアドホックか。型によって関数の定義が異なるか。
はい、そうです。そのHogeなる幻想を与えようということなんですが、パターンマッチのところで結局
Left (Right x) -> ...

みたいに書かないといけないので破れとるなぁと。
確かに :sweat_smile: あと使う側もLeftとRightで剥がす順番を覚えておかないといけないのでtype synonym で別名を付けてる意味…ってなりそうですね…
やはり data か
多分今回はそういうケースではないんだろうとは思いますが、
値コンストラクターのうち2つが明確に「エラーの場合の値」(あるいはその逆)を表しているといえるなら
data Val = E1 | E2 | R

を、
data Err = E1 | E2
data R = R
type Val = Either Err R

と書き換えるのはいいと思いますけどね
「エラーの場合の値」といえなくとも、3つの値コンストラクターがきれいに2つのグループに大別できる、ならいいか
実はいい線いってますそれ。
なるほど、下だけdataもありえるか。。。
Haskell で、associativity をもつ型クラスみたいなのってないのだろうか。
Semigroup?
おおお、そうか semigroup だといけるのか。
ありがとうございます。
いちいち積をあたえなくても、
Assoc type があるみたいですね。
semigroup はassociativity が制約として課されている訳であって、ものは、積によって演算されてしまうので、つぶれているので、
この場合は、そのように考えるならば、

例えば、いっそ identity を付加して、monoid にするとどのような弊害があるのだろうか。

{E1} * {R} = {E1}
{E1} * {E2} = {E1, E2}

などと定義するとして。
Either : Types -> Types -> Types が積とすればいいのか。
これって Haskell で書けるのか?
e a b = Either a b 

でいけるか
read が失敗した時謎の場所で実行時エラーになってreadが原因だとしばらく気が付かなかったことはありますね
readMaybe 使えば良いんですけど
型変数を自由に扱えるほど、Haskell は自由ではないか。
なんかしらの拡張機能がいるのかな。
無理ゲーかもしれない
とりあえずそれだとEitherのLeftとRightが同じ型じゃないといけなくなりそうですね
マグマの時点で同じ型じゃないと演算ダメですし
@wataru007jp has joined the channel
なるほど、たしかに、そうですね。
e a b = either a b //either の頭文字が小文字

だといけるのか