私はこのライブラリを使用してslackbotを構築しようとしています:ちょっと勉強して、うまくいけば、ついにmonads -_-を理解しています。Monadstateのインスタンスがありません
私は、次の種類があります。
data BotState = BotState
{
_appState :: AppState
}
makeLenses ''BotState
type AppState = HM.Map String ChannelState
emptyState :: AppState
emptyState = HM.empty
data ChannelState = ChannelState
{ _counter :: Int}
type Bot = Slack.Slack BotState
をし、私は私のボットを実行します。
initApp = lookupEnv "SLACK_API_TOKEN" >>=
\apiToken -> case apiToken of
Nothing -> throwM ApiTokenMissingException
Just t -> void $ Slack.runBot (Slack.SlackConfig t) runApp $ BotState emptyState
:
runApp :: Slack.Event -> Bot()
runApp [email protected](Slack.Message cid uid body _ _ _) = sendMessage cid "GAH I CAN HAZ CHZBURGHER!"
これは私が追加したい今、正常に動作システムの状態を更新する機能(カウンタをインクリメントする、または他の方法で)
ので、私は私のボットにmodifyState機能を追加します。
modifyState :: (AppState -> AppState) -> Bot()
modifyState f = uses Slack.userState $ view appState >>=
\state -> modifying Slack.userState $ set appState $ f state
これはで壊れる:
modifying
の署名与えられた意味を成し
No instance for (Control.Monad.State.Class.MonadState
(Slack.SlackState BotState) ((->) BotState))
arising from a use of ‘modifying’
In the expression: modifying Slack.userState
In the expression:
modifying Slack.userState $ set appState $ f state
In the second argument of ‘(>>=)’, namely
‘\ state -> modifying Slack.userState $ set appState $ f state’
:
modifying :: MonadState s m => ASetter s s a b -> (a -> b) -> m()
しかし、 Slack.userState
のドキュメントを見て:
userState :: forall s s. Lens (SlackState s) (SlackState s) s s Source
そして:
data SlackState s
... Constructor ...
Instances
Show s => Show (SlackState s)Source
MonadState (SlackState s) (Slack s)Source
それではなぜMonadState
のインスタンスすでにBotState
ではないでしょうか?どうすればこの問題を解決できますか?
のためにいつもここですBotState '、それは' MonadState(SlackState BotState)(( - >)BotState) 'を探しています。 '$'と '> ='のために優先順位の問題のようです - 明示的なかっこを試してみてください。 – user2407038
あなたはそうだ、それは '' Slack.userState $ view appState'を使う '$'のせいだった。 'Slack.userState(view appState)'を使うように変更すると、問題が修正されます。私はそこで何が起こったのか理解したいですか?この特定の状況で '$'が期待どおりに動作しなかったのはなぜですか? ところで、助けてくれてありがとうございました。ポイントを集めたい場合は、答えとして書いてupvote/acceptを受け取りましょう:) –
非常におおまかなことに、 '$'は括弧を末尾に追加すると考えることができます表現。だから、 'Slack.userState $ stuff1 >> = stuff2'は'意図されていないSlack.userState(stuff1 >> = stuff2) 'を使用しています。 'do'ブロックではこの問題は起こりません:' do state < - do Slack.userState $ view appState; Slack.userState $ set appState $ f state'を変更します。あなたが正しく字下げする限り( 'state < - 'と 'modifications'は同じ列で開始しなければなりません)、'; 'の代わりに改行を使うことができます – chi