haskell-jp / questions #82

あ、なるほど、representational 以外の role 持つやつだと表示されるんですね。ありがとうございます、解決しました
解決したみたいでよかったです。
いちおう、8.8.3で
GHCi, version 8.8.3:   :? for help
ghci> :set -XTypeFamilies
ghci> :set -XGADTs
ghci> type family F a
ghci> data T a b c = MkT b (F c)
ghci> :i T
type role T phantom representational nominal
data T a b c = MkT b (F c)
        -- Defined at <interactive>:4:1

でした。
@igrep set the channel topic: お悩み相談専用チャンネル。回答は原則スレッド機能でやりましょう。複数の質問を同時に投稿しやすくするための配慮です。
popl 2011 年からの概念なんですね。勉強せねば。
ありがとうございます。
equivalent な型を同じ role をもつというのですね。
どういう equivalent を持ってくるかが重要で、ここでは representational equivalent という概念を持ってきます。なお、やってる事は基本的に structural equivalent とあまり変わりませんが、role system によって各データ型の equivalent のレベルを調整できる点が異なります。その調整を行うために指定するのが(パラメータの) role です
representational equivalent とは直感的には、実行時に同じ表現を持つということを表します
ありがとうございます。
@hiroyuki.nagata has joined the channel
hourglassパッケージにおける WeekDay https://hackage.haskell.org/package/hourglass-0.2.12/docs/Time-Types.html#t:WeekDayDate を受け取って、「指定した日付から次のhoge曜日まで何日かかるかを返す」関数 daysUntilNext という関数を定義してみました。もっとクールな計算方法があれば教えていただきたいです。
なんかうまいことやれば if とかで分岐しなくて済みそうなんですが、ぱっと思いつきませんでした。
daysUntilNext :: WeekDay -> Date -> Int
daysUntilNext nextWeekDay baseDate =
    if nextWeekDay > baseWeekDay
      then fromEnum nextWeekDay - fromEnum baseWeekDay
      else fromEnum nextWeekDay - fromEnum baseWeekDay + 7
    where
      baseWeekDay = getWeekDay baseDate
例えば、以下のように計算します:
• 今日(2020年4月1日(水))から次の月曜日(2020年4月6日)であれば 5
• 今週日曜日(2020年4月5日)から次の月曜日であれば 1
• 今週月曜日(2020年3月30日)から次の月曜日であれば 7
(fromEnum nextWeekDay - fromEnum baseWeekDay) `mod` 7

すればいいかと思いましたが、月→月が0になってしまうので良くないですね
負の数の剰余は、ちょっと前にTwitterでバズってたツイートがあった気がする
どちらにしても、完全に分岐をなくすのはやっぱ難しそうですね...
少し汚いですが、こんな感じでどうでしょうか?
今試してみたらテスト通りました。ありがとうございます!
いつの間にか cabal から sandbox が消えているんですけど、global environmentを全くいじることなくあるパッケージをghci上で遊んで、遊び終わったら(nix-styleだし別にstore上から消えてろとは言いませんが)environmentから完全に消え去る、ってどうやったらいいんですかね? (てかこれ beginner レベルか?)
beginnerチャンネルがあることを今知った
cabal repl --build-depends=<package> で良いですね
:information_desk_person: beginnersquestions かの区別は特に明確に設けていないので、迷ったら questions でよいです。
:information_desk_person: もう一つ補足: 2019年12月8日に作成して以降、このSlack Workspaceに登録した人は必ずjoinするチャンネルとなってますので、それ以前からいらっしゃる方はjoinするのを推奨します :bow:
あ、 beginners って必ずjoinするチャンネルになってたんですね!
上で言及した、負の数の剰余に関するツイートはこれでした。
https://twitter.com/hisagrmf/status/1244587942502252545
HaskellのmodはRubyやPythonタイプで、かならず0~n-1になると考えていい奴ですね
@mtkaaai has joined the channel
UbuntuイメージのDockerウェブアプリケーションを開発中なんですが、動作確認を手元のUbuntuでビルド→バイナリをDockerイメージにコピーという方法で動作確認していました。これをWindowsでもやろうと思ったのですがもちろんOSが違います。ビルドツールにCabal、GHC-8.8.2を使用していますがWindows上からサクッとクロスコンパイルでUbuntuの実行バイナリ作れたりするでしょうか(ちらっと調べた限りそんな雰囲気はなかった)。それとも動作確認と割り切ってWindowsようのDockerイメージ作るのが早いでしょうか
Docker for Windows で Ubuntuコンテナ内でビルドするのがてっとり早いんじゃないかと思います.
ですよねー。そう甘くはなかった
当方Windows環境がないので確認できませんが、WSLじゃビルドできないんですかね?
ウェブアプリケーションなのでそこまでクロスコンパイル欲求はなく、Windowsのイメージ使って動作確認して済ませてしまいました 。手元で cabal install --install-method=copy --installdir=.. してからコピってます。 https://github.com/kirisaki/prototip-2.kirisaki.dev/blob/master/Dockerfile.win
@tn78adsl has joined the channel
@snisimu has joined the channel
Enum って、特に要素のenumeration typeについてderived instance以外を用いるのって許容されてるんでしょうか? されてるとして、番号が飛び飛びになってるのとか、って許容されてるんでしょうか・・・。
試しにそういうインスタンスを作ってみて、 enumFromThen などのメソッドがちゃんと動くか気になりますね。
まぁ、いずれにしても、すべてのメソッドを則を満たすように実装すれば、飛び飛びになっていても特に問題はないかと思います。
そもそも、 Enum に則があるのかわかんないんですよね…
succ . fromEnum = fromEnum . succ が則なのかとか。これが課されると飛び飛びはあり得なくなりますし。
…_sequentially_ ってどうなんでしょう。或いは、The nullary constructors are assumed to be numbered left-to-right by fromEnum from 0 through n-1.に暗黙についているのが、In the derived instance, なのか In this case , which is of that `Enum` is derivable, なのか… ついてる動詞が_assigned_とかじゃなくて_assumed_なので・・・。
sequentially orderedなのは変換される前の値についての性質であって、`Int`に変換してどう対応させるか、については何も言ってないと思います。
「The nullary constructors are assumed to be numbered left-to-right by fromEnum from 0 through n-1.」はあくまでもderived instanceについての話であって、独自に作る分には関係がないのではないでしょうか。
「あくまでもderived instanceについての話であって」に補足しますと、
「Instances of Enum may be derived for any enumeration type」で始まる段落にあったためです。
同じ文がHaskell 2010 Reportにもあり、そちらでも「Derived instances of Enum」についての話として書かれています。なので、あくまでもderived instanceの文脈だと思っています。
https://www.haskell.org/onlinereport/haskell2010/haskellch11.html#x18-18400011.2
なるほど。となると、基本的に Enum には則はない、ということでいいのかな。
fromEnum (succ x) > fromEnum x とか。
強いて挙げるなら succ maxBound がボトムであることとか、
   enumFrom     x   = enumFromTo     x maxBound
   enumFromThen x y = enumFromThenTo x y bound
     where
       bound | fromEnum y >= fromEnum x = maxBound
             | otherwise                = minBound

でしょうね。
確かに fromEnum (succ x) > succ x も明確に言及されてないですがそうあってほしいですね... :thinking_face:
enumFrom x = x : enumFrom (succ x) where succ x is non-bottomとか課されてないって考えるとちょっと背筋が寒くなるというか……これは sequentially orderedで課されてるって認識でいいんでしょうか。
それはちょっとわからないんですが、一つ重要な見落としがありました。
デフォルトの実装は明らかに飛び飛びになっていることを想定してなさそうなので、もし飛び飛びにしない場合はすべてのメソッドを実装しなきゃですね...
https://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.Enum.html#succ
もちろんわかるはずがない、これ、よくないなあ(というか Double のインスタンスが満たしてないだろうから、課すわけにもいかなかったのかな)
あ、それはそうです。
Float とか Double が Enum のインスタンスになっているところが落とし穴になっていますね.[2.3 .. 10]を評価すると穴の深さがわかります.:sweat_smile: