Closed ggranberry closed 6 years ago
@ggranberry try this!
(False, m) -> do
anEither <- say m config
case anEither of
Left e -> putStrLn ("an error occurred! " <> show e)
Right _ -> return ""
The problem here is that typeclasses generate bad errors :(
You should think of say
as having type IO (Either RequestError ())
, which uses the typeclass instance MonadError e (Either e)
. The reason the very generic mtl type exists is that you can use it in deeper monad stacks where perhaps there are more layers between the IO
and the Either RequestError
.
Your code is forcing GHC to infer say m config
as IO a
. Now IO does have a MonadError
instance, except it's MonadError IOException
-- the weird mismatch between IOException
and RequestError
is what's causing the problem here.
Hope that makes sense. Keep me updated! Thanks for using the library.
@hlian Thanks for the quick and detailed reply! Your comment was incredibly helpful and I'm mostly seeing why it is breaking right now. Though some of the some of the mtl type stuff was a bit above me as this is my first attempt at a small Haskell project.
I went ahead and tried to implement your suggestion and got the same error as before with a few extra ones added. It looks like say isn't being evaluated as IO (Either RequestError ())
from what I'm seeing.
/Users/ranberry/haskell/scraper/src/Notification/SlackBot.hs:38:19: error:
• Couldn't match type ‘IOException’
with ‘Network.Linklater.Types.RequestError’
arising from a functional dependency between:
constraint ‘mtl-2.2.1:Control.Monad.Error.Class.MonadError
Network.Linklater.Types.RequestError IO’
arising from a use of ‘say’
instance ‘mtl-2.2.1:Control.Monad.Error.Class.MonadError
IOException IO’
at <no location info>
• In a stmt of a 'do' block: anEither <- say m config
In the expression:
do { anEither <- say m config;
case anEither of {
Left e -> putStrLn ("an error occurred! " <> show e)
Right _ -> return "" } }
In a case alternative:
(False, m)
-> do { anEither <- say m config;
case anEither of {
Left e -> putStrLn ("an error occurred! " <> show e)
Right _ -> return "" } }
/Users/ranberry/haskell/scraper/src/Notification/SlackBot.hs:40:9: error:
• Couldn't match expected type ‘()’ with actual type ‘Either a0 t0’
• In the pattern: Left e
In a case alternative:
Left e -> putStrLn ("an error occurred! " <> show e)
In a stmt of a 'do' block:
case anEither of {
Left e -> putStrLn ("an error occurred! " <> show e)
Right _ -> return "" }
/Users/ranberry/haskell/scraper/src/Notification/SlackBot.hs:40:19: error:
• Couldn't match type ‘()’ with ‘T.Text’
Expected type: IO T.Text
Actual type: IO ()
• In the expression: putStrLn ("an error occurred! " <> show e)
In a case alternative:
Left e -> putStrLn ("an error occurred! " <> show e)
In a stmt of a 'do' block:
case anEither of {
Left e -> putStrLn ("an error occurred! " <> show e)
Right _ -> return "" }
/Users/ranberry/haskell/scraper/src/Notification/SlackBot.hs:41:9: error:
• Couldn't match expected type ‘()’ with actual type ‘Either t1 t2’
• In the pattern: Right _
In a case alternative: Right _ -> return ""
In a stmt of a 'do' block:
case anEither of {
Left e -> putStrLn ("an error occurred! " <> show e)
Right _ -> return "" }```
@ggranberry silly me! i was missing a runExceptT
call. i updated JPEGbot to illustrate the solution:
@hlian That did the trick, thanks!!
http://lpaste.net/360345
While writing a small slackbot using linklater I noticed that providing a Message and Config object to 'say' returned a value that violates functional dependencies. Can anyone provide any insights into what I'm doing wrong here?