[Haskell-cafe] Monad layering and DSL

Tom Ellis tom-lists-haskell-cafe-2013 at jaguarpaw.co.uk
Sun Jan 25 23:12:17 UTC 2015


On Sun, Jan 25, 2015 at 11:29:27PM +0100, Gautier DI FOLCO wrote:
> 2015-01-25 22:47 GMT+01:00 Tom Ellis <
> tom-lists-haskell-cafe-2013 at jaguarpaw.co.uk>:
> > On Sun, Jan 25, 2015 at 10:39:48PM +0100, Gautier DI FOLCO wrote:
> > > 2015-01-25 9:37 GMT+01:00 Tom Ellis <
> > > tom-lists-haskell-cafe-2013 at jaguarpaw.co.uk>:
> > > > On Sat, Jan 24, 2015 at 07:46:52PM +0100, Gautier DI FOLCO wrote:
> > > > > data ImapF next =
> > > > >          Select DirectoryName (Maybe DirectoryDescription -> next)
> > > > >        | Noop (DirectoryDescription -> next)
> > > > >        | Search MailSearch (Maybe [UID] -> next)
> > > > > -- Functor instance
> > > > > type Imap = Free ImapF
> > > > >
> > > > > searchAll :: Imap (Maybe [UID])
> > > > > searchAll = liftF $ Search undefined id
> > > > > select :: DirectoryName -> Imap (Maybe DirectoryDescription)
> > > > > select directory = liftF $ Select directory id
> > > > >
> > > > > My main problem is the following: if I do a select of an unknown
> > > > > directory, I should stop the computation.
> > > >
> > > > What do you mean you "should stop the computation"?  Do you mean the
> > > > interpretation of the free monad should be forced to stop?  If so,
> > > > doesn't making the type of the `Select` constructor
> > > >
> > > >     Select DirectoryName (DirectoryDescription -> next)
> > > >
> > > > achieve this?  That way if the interpreter talks issues a select
> > > > command to the server and fails to receive a `DirectoryDescription`
> > > > in return then it is forced to stop.
> > >
> > > If I do it this way, the evaluation is forced to be stopped, I have no
> > > way to react to this error.
> >
> > Could you explain more precisely what you are trying to achieve, perhaps
> > with an example?
> 
> In fact I'm looking for a practical way to alter Imap to change it
> temporarily or not, globally or locally in a failable monad.
> 
> Example:
> 
> select "Unknown" -- will fail
> doSomethingUnrelated
> 
> failableLessMode
> select "Unknown" -- will fail
> doSomethingUnrelated -- unreached expression
> -- or
> select "Unknown" <!!> $ do-- will fail
>   doSomethingUnrelated -- unreached expression
> 
> where <!!> :: Imap (Maybe a) -> (a -> Imap b) -> Imap (Maybe b)

It's still not completely clear. A you looking for an implementation of
<!!>?  That is essentially just MaybeT and exists for any monad:

(<!!>) :: (Functor m, Monad m) => m (Maybe a) -> (a -> m b) -> m (Maybe b)
m <!!> f = m >>= (\x -> case x of
                     Nothing -> return Nothing
                     Just a  -> fmap Just (f a))


More information about the Haskell-Cafe mailing list