IT練習ノート

IT関連で調べたこと(実際は嵌ったこと)を書いています。

ServantのルーティングでのIO

ServanthandlerでのIOの取り回しのサンプルはWebに情報があるのですが、:>で記述していくルーティングでのIOの取り回しがわからず四苦八苦していました。

HasServerという型クラスでルーティングを記述していきますが、このクラス自体にIOが明示的にはない(と思う)ので、ルーティング中にデータベースとかにアクセスしたい場合どうするのかと疑問に思っていました。ソースを読んでも、Delayedという処理を貯めといて最後に処理をする仕組みのため、なかなかコードが読めませんでした。

さらにDelayedのコードを読むとデータコンストラクタ中にDelayedIOがあります。これが、隠蔽化されているようにも思えますが、DelayedIO定義自体は隠蔽化はしていません。DelayedIOという名前にIOがついているので、これを使えばIOができることは推測できるのですが、具体的にどうすればよいかわかりませんでした。

DelayedIOの定義をみると、モナドトランスフォーマーのスタックの最後(最初?)にIOがあるので、これが目標になります。結局、liftしてやればIOができるということでした。

newtype DelayedIO a = DelayedIO { runDelayedIO' :: ReaderT Request (ResourceT (RouteResultT IO)) a }
  deriving ( Functor, Applicative, Monad, MonadIO, MonadReader Request, MonadBase IO, MonadThrow, MonadResource)

DelayedIOを手繰り寄せるには、withRequestが使えます。

Servant.Server.Internal.RoutingApplication

このwithRequestIOを使うコードを下記を参考に追加してみました。lift自体はControl.Monad.BaseliftBaseを使います。

元ネタ

Jacob Errington | Token authentication with Servant

IOを追加したコード

Token Authentication with Servant with IO

ghciの使い方

プロンプトを変える

:set prompt "foo>"

バンドされている情報を見る

:show bindings
foo>let x = 123
foo>let y = "abc"
foo>:show bindings
x :: Num t => t = _
y :: [Char] = _
foo>

ロードされているモジュールを確認する

:show module
foo>:l MyWebApp1.hs
[1 of 1] Compiling Main             ( MyWebApp1.hs, interpreted )
Ok, modules loaded: Main.
foo>:show modules
Main             ( MyWebApp1.hs, interpreted )
foo>

インポートされている情報を確認する

:show imports
foo>import Data.Set
foo>:show imports
import Data.Set
:module +*Main -- added automatically
foo>import Servant
foo>:show imports
import Data.Set
import Servant
:module +*Main -- added automatically
foo>

エディタを開く

:edit

言語拡張情報の確認

:show language
foo>:set -XConstraintKinds
foo>:show language
base language is: Haskell2010
with the following modifiers:
  -XConstraintKinds
  -XNoDatatypeContexts
  -XNondecreasingIndentation
foo>

main関数ではない関数をmainとして実行する

:main [foo] op1 op2 op3

historyファイルの場所

~/.ghc/ghci_history

Polynomialを整形して表示する

Math.PolynomialパッケージのPoly型のShowは内部構造をそのまま文字列表現するので、読みにくいときがあります。そこで、多項式を数式のように表示するサンプルを書いてみました。

polynomial: Polynomials