モナドと一口に言っても内部実装色々あるので、同じ機能のモナドを色々な書き方で書いてみます。 要件 あまり複雑にしてもアレなので、State,WriterとIOの制約くらいにしておきます。 インスタンスはFunctor, Applicative, Monadのみ 内部にIntで0開始のカウンタと、DList Logで表現されるログを持つ incr :: Int -> DSL ()でカウンタを増減し、ログにI iを追加 reset :: DSL ()でカウンタを0に戻し、ログにRを追加 current :: DSL ()で標準出力に現在のカウントを出力。文脈内でそれ以外のIOは不可能とする runDSL :: DSL () -> IO (Int, [Log])でDSLを実行し、最後のカウンタの値とログを返す。 Logデータ型はこんな感じにして共通に使用し、
![モナドの実装いろいろ - Qiita](https://cdn-ak-scissors.b.st-hatena.com/image/square/c5593fc06f724cc1c916932fb9d82d1f50663fb0/height=288;version=1;width=512/https%3A%2F%2Fqiita-user-contents.imgix.net%2Fhttps%253A%252F%252Fcdn.qiita.com%252Fassets%252Fpublic%252Fogp-background-1150d8b18a7c15795b701a55ae908f94.png%3Fixlib%3Drb-1.2.2%26w%3D1200%26mark%3Dhttps%253A%252F%252Fqiita-user-contents.imgix.net%252F~text%253Fixlib%253Drb-1.2.2%2526w%253D840%2526h%253D380%2526txt%253D%2525E3%252583%2525A2%2525E3%252583%25258A%2525E3%252583%252589%2525E3%252581%2525AE%2525E5%2525AE%25259F%2525E8%2525A3%252585%2525E3%252581%252584%2525E3%252582%25258D%2525E3%252581%252584%2525E3%252582%25258D%2526txt-color%253D%252523333%2526txt-font%253DAvenir-Black%2526txt-size%253D54%2526txt-clip%253Dellipsis%2526txt-align%253Dcenter%25252Cmiddle%2526s%253D61591dc3896b32f82e54efd28349990c%26mark-align%3Dcenter%252Cmiddle%26blend%3Dhttps%253A%252F%252Fqiita-user-contents.imgix.net%252F~text%253Fixlib%253Drb-1.2.2%2526w%253D840%2526h%253D500%2526txt%253D%252540philopon%2526txt-color%253D%252523333%2526txt-font%253DAvenir-Black%2526txt-size%253D45%2526txt-align%253Dright%25252Cbottom%2526s%253D9c959db220b6c4f62b0343eefbf9829c%26blend-align%3Dcenter%252Cmiddle%26blend-mode%3Dnormal%26s%3Dd230adfd8ef017e7aecaa22e047153f8)