News for hackers. Stuff that matters.
Re:Reflecting on Haskell in 2016 by dualogy on Monday December 26, 2016 @02:33AM (#13257363)
> I'm of the opinion that worked examples are often worse than no documentation.

I'm not, especially for the many more-abstract-concepts. 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.. A lot of explanations in the Haskell ecosystem are super-abstract and forever-self-referencing and as someone arriving with a sense of urgency of pumping out Brave New Apps to the world, I'm always itching and saying "OK transformables turn foldables that contain applicatives into functors that fold applicatives into transformables so in other words I CAN SKIP THIS RITE?" Leave it in the shadows as it was clearly a priority to neatly have the abstractions that allowed making MayBe/IO/Lists etc as usable language features in there.

On the other hand I don't want to end up writing 10k lines that could have been expressed in 500 had I grasped the more obtuse abstractions.

Experience tells me that once you happen across a simple real-world use, the shocking simplicity of what was encrypted in mathematical-logical-calculi lingo is instantly revealed. The absence of such "code examples" (with a real-world touch, not just x,y,z,f,g,h identifiers in a senseless vacuum) is truly annoying and goes all the way from the Wiki to Diehl's articles to various books.. it's hyperprevalent throughout the community.

Re:Reflecting on Haskell in 2016 by dllthomas on Monday December 26, 2016 @03:37AM (#13257513)
> 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
Re:Reflecting on Haskell in 2016 by greenrd on Monday December 26, 2016 @06:57AM (#13257945)
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.

Re:Reflecting on Haskell in 2016 by dllthomas on Monday December 26, 2016 @12:27PM (#13258962)
> 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!