LoginSignup
5
2

More than 5 years have passed since last update.

extensibleのAssociateを使ったEff型を具体型にする

Last updated at Posted at 2017-08-27

※ 本記事はextensible-effectsパッケージではなくextensibleパッケージの
Data.Extensible.Effectモジュールについての記事です

解答

context :: ( Associate "greet" (WriterEff [String]) xs
           , Associate "message" (WriterEff [String]) xs
           ) => Eff xs ()

 上記の型を具体化すると

context :: Eff '["greet" >: WriterEff [String], "message" >: WriterEff [String]] ()

という具体型になる。

Data.Extensible.Effectでの抽象的なEff型

 extensible-effectsではこのような抽象化されたEff型で、Writerモナド相当の操作ができましたが

context :: ( Member (Writer [String]) r
           ) => Eff r ()
context = do
  tell ["hi"]
  tell ["thanks !"]

 extensibleパッケージでは、WriterEff, ReaderEffなどの
Data.Extensible.Effectでの作用を名前付き(Symbol付き※1)で管理できるので、
重複した作用を別のものとして扱うことができる。

context :: ( Associate "greet" (WriterEff [String]) xs
           , Associate "message" (WriterEff [String]) xs
           ) => Eff xs ()
context = do
  tellEff #greet ["hi"]
  tellEff #message ["extensible, OverloadedLabels, and TypeApplications is great"]
  tellEff #greet ["thanks !"]
-- これらを
-- leaveEff . runWriterEff @ "message" . runWriterEff @ "greet"
-- すると
-- (((),["hi","thanks !"]),["extensible, OverloadedLabels, and TypeApplications is great"])
-- という値が得られる

※1

 String[Char])を種に昇格するとSymbolになるっぽい? まだ調べてない。

Data.Extensible.Effectでの具体的なEff型

 上の型

context :: ( Associate "greet" (WriterEff [String]) xs
           , Associate "message" (WriterEff [String]) xs
           ) => Eff xs ()

を解凍する関数

leaveEff . runWriterEff @ "message" . runWriterEff @ "greet"

の型をGHCのtyped hole機能で調べてみると

(Monoid w, Monoid w1)
=> Eff '["greet" >: WriterEff w, "message" >: WriterEff w1] a
   -> ((a, w), w1)

と出る。

 ちょうど我々がそこに当てはめているMonoid[String]なので、

leaveEff . runWriterEff @ "message" . runWriterEff @ "greet"
:: Eff '["greet" >: WriterEff [String], "message" >: WriterEff [String]] ()
   -> (((), [String]), [String])

である。

 なので

context :: Eff '["greet" >: WriterEff [String], "message" >: WriterEff [String]] ()

である。

余談

 #fooというのはOverloadedLabels拡張の機能で、@ BarというのはTypeApplications拡張の機能。

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2