ここは俺の備忘録だ

少なくとも日本語での言及が少ない話をするつもりです

runSTにおける関数合成の失敗—Higher Rank Typesにおける型推論の落とし穴

余談

2つの事柄を題に要約する言い回しとして「あるいは」以外を見つけないとブログの題があるいはだらけになってしまう…

本題

より高ランクな型を低いランクの型パラメータで表すことはできない。 従って通常のランク1であるような関数somethingについて、something . runSTのような関数合成は上記ツイートのようなエラーを起こす。 しかしそのままだとrunST $ doが使えず非常に不便であるため、GHC7から$について推論する特殊ルールが追加されている。

これもまたHaskellに数多ある知っていれば当然であるが、知らねば型エラーから類推するのは難しい一例と言える。 まぁともあれ、ランク2の型はSTのスコープ制限は勿論のこと、 AllowAmbiguousTypes拡張と組み合わせてfromIntegralした数値を使い回すのに非常に便利だったりする(申し訳程度の擁護)。

関数適用演算子$は空気の如く重要であるため、色々特別扱いを受けている。 例えばLevity Polymorphismが知られている。 Levity Polymorphismはhaskellの意味論的でいうボトムに持ちあげられている型と持ちあげられていない型の間で多相性を行う実装だ。 意味論についてはここで概観が読める。

Haskell/Denotational semantics - Wikibooks, open books for an open world

もっと実装にフォーカスして言ってしまえば、unboxな型とboxedな型で関数に多相性を持たせようという 取り組みである。GHCでは所謂MagicHashが付いた型をunboxedな型として扱っており、 Intに対するInt#が明示的なunboxedを表す型であった。この間で多相性を持たせんとする。 以下を参照するのが良いだろう。

stackoverflow.com