[HN Gopher] Free monads from scratch
       ___________________________________________________________________
        
       Free monads from scratch
        
       Author : siraben
       Score  : 14 points
       Date   : 2022-05-29 17:27 UTC (5 hours ago)
        
 (HTM) web link (siraben.dev)
 (TXT) w3m dump (siraben.dev)
        
       | huqedato wrote:
       | Monads are hard. I read many articles explaining what a monad is
       | and what is good for but I never really grasped the concept. I
       | probably have to learn Haskell.
        
         | btown wrote:
         | https://fsharpforfunandprofit.com/rop/ is by far my most
         | recommended starting point, using a railway analogy. To grossly
         | oversimplify, as far as I can tell, a monad is a type well-
         | defined enough that you can hook up functions that work with it
         | in a "parallel tracks" manner. So it's great for chained
         | functions, and reusing and weaving those functions, where you
         | accumulate information other than the "obvious" thing to return
         | as you go along, like errors or logging or IO.
        
           | huqedato wrote:
           | I know that also. Not great not terrible. Still couldn't
           | clarify the thing.
        
         | kelseyfrog wrote:
         | From personal experience Scala also works. It's 100% possible
         | to learn monads using https://scastie.scala-lang.org/ as a
         | scratch pad.
        
       | armchairhacker wrote:
       | > While it looks like boilerplate, we can more or less
       | mechanically write out the instances...
       | 
       | Yes so why doesn't some GHC extension do this?
       | 
       | The issue I have with this and Functors and Monads and Monad
       | transformers is that there is a lot of boilerplate. I wish i
       | could apply f x y instead of lift $ f <$> x <*> pure y. It would
       | be awesome if there was a ghc extension which, whenever it
       | encounters something like '(a -> b -> c) applied to (f a and f b,
       | expected to return g (f c))' it automatically adds the
       | appropriate 'fmap', 'bind', 'pure', 'lift', 'inj', 'Impure' etc.
       | Then combined with do-notation, you can write truly imperative-
       | looking code, without having to manually convert 'a' and 'State
       | a' and 'Reader a' and 'Exception a' into '(State :+: Reader :+:
       | Exception) a'.
       | 
       | IMO free monads are an implementation detail for how to enable
       | typed effects and subtypes in a pure language. They're still kind
       | of important for users to understand, but they would be easier to
       | explain if you let users write imperative-looking code first and
       | then convert it into free monads. That would fix the question
       | most people have when learning about category theory, "why?" -
       | most people don't know what to make with category theory
       | abstractions because they don't know what they're for.
        
         | siraben wrote:
         | > I wish i could apply f x y instead of lift $ f <$> x <*> pure
         | y.
         | 
         | In "Applicative Programming with Effects"[0], the authors use
         | such a notation, and even leave it as an exercise to implement
         | it in Haskell using MultiParamTypeClasses:
         | 
         | > Given Haskell extended with multi-parameter type classes,
         | enthusiasts for overloading may replace '[' and '[?]' by
         | identifiers i[ and ]i with the right behaviour.
         | 
         | So they have code that looks like                 eval :: Exp v
         | -> Env v -> Int       eval (Var x) = fetch x       eval (Val i)
         | = [ i [?]       eval (Add p q) = [ (+) (eval p) (eval q) [?]
         | 
         | > Yes so why doesn't some GHC extension do this?
         | 
         | It's possible to derive the functor instance automatically if
         | the data type is built from products, sums and arrows. However
         | even for Applicatives you can't do this in general because
         | there can be many lawful Applicative instances for the same
         | type, for instance[1] for lists.
         | 
         | [0] http://strictlypositive.org/IdiomLite.pdf
         | 
         | [1]
         | https://hackage.haskell.org/package/base-4.16.1.0/docs/Contr...
        
       ___________________________________________________________________
       (page generated 2022-05-29 23:02 UTC)