Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> I have yet to see a followable code case demonstrating the use of custom monads (not IO or Maybe or lists etc) that show why (when) I should ever write my own, to understand even just using them better generally.

For an interpreter I'm working on I have an "Eval" type, implemented as a newtype wrapper around a transformer stack. This gives me a context to work in where I can access variables in scope (carried in a ReaderT) and fail with error (handled by an ExceptT). The code (simplified) looks a little like this:

    {-# LANGUAGE GeneralizedNewtypeDeriving #-}
    {-# LANGUAGE LambdaExpr #-}
    newtype Eval a = Eval (Reader EvalContext (ExceptT String m) a)
        deriving (Functor, Applicative, Monad, MonadReader EvalContext, MonadError String)

    lookupVariable :: Variable -> Eval Value
    lookupVariable v = asks (findVarInContext v) >>= \case
        Nothing -> throwError ("unbound variable: " ++ show v)
        Just result -> pure result

    lookupFunction :: FunctionName -> Eval ([Value] -> Value)
    lookupFunction f = asks (findFuncInContext f) >>= \case
        Nothing -> throwError ("unknown function: " ++ show f)
        Just f' -> pure f'

    evaluateFunction :: Function -> Eval Value
    evaluateFunction (Function name args) =
        lookupFunction function <*> mapM evaluateExpr args


That looks like more of a combination of existing monads than a truly new monad.

I must admit that I can't remember ever creating my own monad from scratch.


> That looks like more of a combination of existing monads than a truly new monad.

Well sure, but if we're going to exclude those then the grandparent's ask is a bit high: either we present something useless and pedagogic, or we present something useful that exists in a library somewhere, or we present something new and useful... that we should then also put in a library somewhere!




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: