Last active
May 16, 2023 15:26
-
-
Save tokiwoousaka/b62961fe256950c11464 to your computer and use it in GitHub Desktop.
関数型LT大会発表資料
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Main where | |
import Game.NovelMonad | |
import Game.NovelMonad.SimpleInterpreter | |
import Story | |
main :: IO () | |
main = simpleInterpret defaultConfig novelMain | |
novelMain :: Novel () | |
novelMain = do | |
talk Narrator "" | |
talk Narrator "Operationalモナドで紡ぐ物語" | |
talk Narrator "" | |
talk Narrator " ちゅーん(@its_out_of_tune)" | |
talk Narrator " Haskell lover" | |
trunOverThePage | |
shortStory | |
aboutNovelMonad | |
----- | |
aboutNovelMonad :: Novel () | |
aboutNovelMonad = do | |
talk Narrator "" | |
talk Narrator "はいw" | |
talk Narrator "" | |
talk Narrator "ショートストーリー圏論マン" | |
talk Narrator "楽しんで頂けたでだろうか" | |
talk Narrator "" | |
trunOverThePage | |
talk Narrator "RPGやノベルゲームのシナリオは、" | |
talk Narrator "専用のDSLを用いて記述し" | |
talk Narrator "それをパース/インタプリタ実行するのが" | |
talk Narrator "もっとも良く用いられる手法だと思われる。" | |
trunOverThePage | |
talk Narrator "では、今回の掛け合いの場合は、" | |
talk Narrator "どのようになっているか見てみよう。" | |
talk Narrator "" | |
talk Narrator "(実際に見てもらう)" | |
talk Narrator "" | |
trunOverThePage | |
talk Narrator "しかしそれには、以下のような問題がある" | |
talk Narrator "" | |
talk Narrator " -> 学習コストが高い" | |
talk Narrator " -> 言語としての完成度があまり高くない" | |
talk Narrator " (出来る事が少ない)" | |
talk Narrator " -> 実装コストがめちゃ高い" | |
trunOverThePage | |
talk Narrator "モナドとは、一般化した手続きである。" | |
talk Narrator "RPGやノベルゲームのシナリオは手続きである" | |
talk Narrator "" | |
talk Narrator "先ほどお見せしたように、" | |
talk Narrator "専用のモナドを実装する事で" | |
talk Narrator "ゲームのシナリオを手続き的に、" | |
talk Narrator "良い感じに書けるようになる" | |
trunOverThePage | |
talk Narrator "IOアクションを追加するだけではダメなのか?" | |
talk Narrator "" | |
talk Narrator "### IOの分離 ###" | |
talk Narrator " -> ゲームシナリオとは無関係なIOアクションを分離" | |
talk Narrator " -> 型を分離する事による問題の切り分け" | |
talk Narrator "" | |
talk Narrator "### シナリオとゲーム本体の分離 ###" | |
talk Narrator " -> 上手く実装すればゲーム本体とシナリオを分離可能" | |
talk Narrator " -> GUIが実装されてなくてもCUI上で簡単にシミュレート" | |
trunOverThePage | |
talk Narrator "専用DSLで問題となっていた事は大体解消される" | |
talk Narrator "" | |
talk Narrator " -> 学習コスト" | |
talk Narrator " いくつかのIOアクションを覚えれば良い" | |
talk Narrator " Haskellの制御構文が使える" | |
talk Narrator " -> 言語としての完成度" | |
talk Narrator " Haskell上でHaskellそのまま書けるんですよ?" | |
talk Narrator " なので当然、モナディック関数使いたい放題!!" | |
trunOverThePage | |
talk Narrator "皆さんの声" | |
talk Narrator "" | |
talk Narrator "「でもお高いんでしょう?」" | |
talk Narrator "(開発コストが)" | |
talk Narrator "" | |
trunOverThePage | |
talk Narrator "" | |
talk Narrator "そこでOperationalモナドですよ!!!" | |
talk Narrator "" | |
talk Narrator "" | |
talk Narrator "(ここで会場がどよめく)" | |
talk Narrator "" | |
trunOverThePage | |
talk Narrator "NovelMonadの実装がどのようになっているか、" | |
talk Narrator "実際に見てみよう。" | |
talk Narrator "" | |
talk Narrator "(実際に見てもらう)" | |
talk Narrator "" | |
trunOverThePage | |
talk Narrator "ご覧頂いたように、とても簡単に、" | |
talk Narrator "新たなモナドを作ることができる" | |
talk Narrator "" | |
talk Narrator "何故こんな事ができるのだろうか?" | |
trunOverThePage | |
talk Narrator "Operationalの仕組み" | |
talk Narrator "" | |
talk Narrator " -> CoYoneda" | |
talk Narrator " 任意の型をFunctorにする" | |
talk Narrator " 圏論から生まれたヤバイ仕組み" | |
talk Narrator " -> Free" | |
talk Narrator " 任意のFunctorをMonadにする" | |
talk Narrator " 圏論から生まれたヤバイ仕組み" | |
talk Narrator "" | |
talk Narrator "この二つが組み合わされば任意の型がMonadになるのは、" | |
talk Narrator "自明である。な、なんだっt(ry" | |
trunOverThePage | |
talk Narrator "本日のまとめ" | |
talk Narrator "" | |
talk Narrator " 圏論ヤバイ、でも..." | |
talk Narrator " 圏論の恩恵を受けたHaskellはめっちゃ便利" | |
talk Narrator "" | |
talk Narrator " ゲームに限らず、ちょっとしたDSLが欲しくなったら" | |
talk Narrator " HaskellでOperationalモナドを使おう!" | |
talk Narrator "" | |
trunOverThePage | |
talk Narrator "" | |
talk Narrator " ありがとうございました! " | |
talk Narrator "" | |
trunOverThePage |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Story where | |
import Game.NovelMonad | |
shortStory :: Novel () | |
shortStory = do | |
(boy, girl) <- createActors | |
trunOverThePage | |
talk boy "今日は良い天気だなぁ!昨日までの雨が嘘みたいだ!" | |
talk Narrator "日の光がさんさんと降り注ぐ昼下がり。" | |
talk Narrator $ actorName boy ++ "はパソコンのキーを叩きながら言った。" | |
talk girl "本当ね。" | |
talk Narrator $ actorName girl ++ "がエクセル方眼紙の資料を纏めながら答える。" | |
trunOverThePage | |
talk Narrator "リリース日まであと21時間、さまざまな困難を乗り越え" | |
talk Narrator "プロジェクトは収束を迎えようとしていた。" | |
talk Narrator "" | |
talk boy "さあ、もうお昼だね、一緒にご飯でも食べに行かないかい?" | |
talk girl "素敵! わたし、この近くに素敵なパスタ屋さんを知っているの。" | |
talk Narrator "と、その時である..." | |
trunOverThePage | |
talk siyouhenko "ふふふふ!そうはさせないわよ!!" | |
talk Narrator "バーン!大きな音を立て扉が開け放たれ、" | |
talk Narrator "怪しげな女が部屋に飛び込んできた!" | |
trunOverThePage | |
talk boy "誰だお前は!" | |
talk siyouhenko $ "私の名は" ++ actorName siyouhenko | |
talk siyouhenko "お前たちのプロジェクトはもう終わりだ!" | |
talk Narrator "なんという事だろう。リリース間近の仕様変更、" | |
talk Narrator "未だかつて、この脅威から逃げられたエンジニアは" | |
talk Narrator "一人足りとも存在しないのだ。" | |
trunOverThePage | |
talk boy "おお!どうしたら良いんだ!" | |
talk girl $ "助けて!" ++ actorName kenronman ++ "!" | |
talk Narrator "その時、まばゆい光とともに" | |
talk Narrator "屈強な男がプロジェクトルームに飛び込んできた!" | |
trunOverThePage | |
talk kenronman "待たせてすまない、後はこの俺に任せてくれ!" | |
talk siyouhenko $ "来たわね" ++ actorName kenronman ++ "、でも無駄よ!" | |
talk siyouhenko "今日の私は今までとは一味違うわ!" | |
talk siyouhenko "実現には、大半のテーブル定義を変更する必要があるの!" | |
trunOverThePage | |
special --必殺技発動 | |
talk siyouhenko "まっ・・・まいったー!!" | |
talk Narrator $ "怪人" ++ actorName siyouhenko ++ "は、ほうほうのていで退散した" | |
talk Narrator "" | |
talk boy $ "すごいぞ!" ++ actorName kenronman ++ "!" | |
talk girl $ "どうもありがとう!" ++ actorName kenronman ++ "!" | |
talk Narrator $ "こうして今日もまた、" ++ actorName kenronman ++ "の手によって、" | |
talk Narrator $ "プロジェクトがひとつ、救われたのであった。" | |
trunOverThePage | |
talk Narrator "" | |
talk Narrator " 〜 Fin ~ " | |
talk Narrator "" | |
trunOverThePage | |
--- | |
special :: Novel () | |
special = do | |
s <- selectChoices $ do | |
talk kenronman "ぐぬぬ。。。" | |
talk kenronman "ならば、これでも喰らえ!" | |
case s of | |
MonadPanchi -> do | |
talk kenronman "自己関手の圏におけるモノイド対象!" | |
talk kenronman "必殺!モナドパーンチ!" | |
SoutuiBeam -> do | |
talk kenronman "いでよ!対となる圏からの射!" | |
talk kenronman "必殺!双対ビーム" | |
NaturalSmash -> do | |
talk kenronman "これぞ圏論の真髄、はじまりの力、喰らえ!" | |
talk kenronman "自然変換スマッシュ!" | |
data Specials = MonadPanchi | SoutuiBeam | NaturalSmash deriving (Enum, Bounded) | |
instance Choices Specials where | |
showItem MonadPanchi = "モナドパンチ" | |
showItem SoutuiBeam = "双対ビーム" | |
showItem NaturalSmash = "自然変換スマッシュ" | |
--- | |
createActors :: Novel (Actor, Actor) | |
createActors = do | |
boyName <- getStrLn (talk Narrator "男の子の名前を入力してね") | |
boy <- return $ Actor | |
{ actorName = boyName | |
, actorSex = Boy | |
} | |
girlName <- getStrLn (talk Narrator "女の子の名前を入力してね") | |
girl <- return $ Actor | |
{ actorName = girlName | |
, actorSex = Girl | |
} | |
return (boy, girl) | |
kenronman :: Actor | |
kenronman = Actor | |
{ actorName = "圏論マン" | |
, actorSex = Boy | |
} | |
siyouhenko :: Actor | |
siyouhenko = Actor | |
{ actorName = "仕様変更" | |
, actorSex = Girl | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment