ec changed the topic of #elliottcable to: #
alexgordon has quit [Quit: Computer has gone to sleep.]
<joelteon> ugh this project makes me feel unclean
<joelteon> I have a Tryable instance for IO, StateT s IO, and ExceptionP ... IO
sharkbot has quit [Remote host closed the connection]
sharkbot has joined #elliottcable
Sgeo has quit [Quit: No Ping reply in 180 seconds.]
Sgeo has joined #elliottcable
eligrey has quit [Quit: Leaving]
cloudhead has joined #elliottcable
cloudhead has quit [Ping timeout: 245 seconds]
cloudhead has joined #elliottcable
wudofyr has quit [Remote host closed the connection]
wudofyr has joined #elliottcable
wudofyr has quit [Remote host closed the connection]
wudofyr has joined #elliottcable
yorick has joined #elliottcable
Sorella has joined #elliottcable
Sorella has joined #elliottcable
cloudhea1 has joined #elliottcable
cloudhead has quit [Ping timeout: 264 seconds]
eligrey has joined #elliottcable
cloudhea1 has quit [Ping timeout: 245 seconds]
jesusabdullah has joined #elliottcable
<jesusabdullah> knew I was forgetting somethin'
<joelteon> you were bitch
<jesusabdullah> that's right!
alexgordon has joined #elliottcable
<joelteon> so guys
<jesusabdullah> so
<joelteon> I just used RankNTypes and NoMonomorphismRestriction in a module
<joelteon> for an actual reason
<joelteon> how many points is that
<joelteon> I think it's 50
<alexgordon> joelteon: -50 for making your code unreadable to 90% of programmers!
<alexgordon> joelteon: just think what ec's score is
<jesusabdullah> dangit joelteon that's not javascript
<jesusabdullah> for shaaame
<joelteon> ok
<joelteon> so it's +50 for being cool
<joelteon> -50 for being too cool
<joelteon> i broke even again
<alexgordon> joelteon: wtf is a monomorphism restriction anyway
<jesusabdullah> lol
<purr> lol
<alexgordon> joelteon: hm. read the wiki on it, don't understand what purpose it serves
<alexgordon> why not just include a type signature lol
<joelteon> ok, well, see
<joelteon> I have a logger helper function
<joelteon> logInfo
<joelteon> and it needs to fetch the current time and do other IO, but it also needs to be agnostic about what monad it's acting in
<joelteon> because I'm using both the generic MonadIO m and ExceptionP ... SafeIO, which is pipes-safe's wrapper monad
<joelteon> so I defined a helper logWith :: (forall a. Monad m => IO a -> m a)
<joelteon> err
<joelteon> so I defined a helper logWith :: (forall a. Monad m => IO a -> m a) -> Text -> m ()
<joelteon> oh whoops
<joelteon> one more try
<joelteon> so I defined a helper logWith :: Monad m => (forall a. IO a -> m a) -> Text -> m ()
<joelteon> there we go, much better
<joelteon> because inside the body of logWith, it applies the function it receives, f, to IO actions that have different return types
<alexgordon> man I hate haskell sometimes
<alexgordon> lol
<purr> lol
<joelteon> time <- f getZonedTime
<joelteon> f $ putStrLn logMessage
<joelteon> and so you see
<joelteon> if I made it just take (IO a -> m a), the type would be restricted to (IO ZonedTime -> m ZonedTime)
<joelteon> and putStrLn x obviously doesn't have the type IO ZonedTime
<joelteon> the forall allows f to be polymorphic within the body of logWith
<joelteon> NoMonomorphismRestriction prevents logInfo and logInfoIO from both trying to act inside MonadIO m, because SafeIO isn't a MonadIO instance obviously
<joelteon> all logWith knows about f is that it can transform IO actions into actions inside the monad it actually wants
<alexgordon> -_-
<joelteon> honestly it's amazing the compiler is capable of this
<alexgordon> joelteon: "just because you *can*, doesn't mean you *should*"
<joelteon> well
<joelteon> it definitely makes generalizing log easier
cloudhead has joined #elliottcable
<joelteon> ok i have a question here
<joelteon> for each client/server pair, there's a thread handling reading from the client and one reading from the server
<joelteon> if I encounter an exception during either, I have this function isRetryable that detects whether I can retry connecting to the client or the server
<joelteon> but I use it twice
<joelteon> once inside the client's Proxy
<joelteon> and once outside, once the client has terminated, I check whether the error is retryable
<joelteon> because when the client Proxy throws an exception, the parent thread catches it and returns it as Left
<joelteon> so what's happening now is
<joelteon> readloop -> exception -> show message, rethrow -> parent thread catches
<joelteon> but should I just
<joelteon> readloop -> exception -> propogates to parent thread, which handles showing messages
<joelteon> because the parent thread is the one who knows how to cleanly restart everything, but the parent thread *shouldn't* be concerned with displaying messages to the user
<joelteon> I could make an ADT that wraps an Exception, I guess
<joelteon> Retryable e or NonRetryable e
<joelteon> and then don't bother checking within the parent thread
<joelteon> but then both the client thread and the server thread are gonna be using isRetryable
yorick has quit [Remote host closed the connection]
<joelteon> hm
<joelteon> I dunno, what SHOULD I do
<joelteon> I can't just return Left ex because there's some exception-related short circuiting in pipes-safe, I have to rethrow it
cloudhead has quit [Ping timeout: 264 seconds]