ServantチュートリアルのBasic認証でIO
http://haskell-servant.readthedocs.io/en/stable/tutorial/Authentication.html
チュートリアルだとユーザIDパスワードチェックのコードがハードコードされています。一見、どこでIOできるのかわからなかったので試してみました。
ServantのルーティングでのIO
Servant
でhandler
での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
このwithRequest
でIO
を使うコードを下記を参考に追加してみました。lift
自体はControl.Monad.Base
のliftBase
を使います。
元ネタ
Jacob Errington | Token authentication with Servant
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
は内部構造をそのまま文字列表現するので、読みにくいときがあります。そこで、多項式を数式のように表示するサンプルを書いてみました。