Multi-parameter context constraints in haskell











up vote
1
down vote

favorite












I'm currently reading the paper Monad Transformers Step by Step
by Martin Grabmüller.



Theres a part in the paper where he lists off the following instance declaration:



instance (MonadError e m) => MonadError e (ReaderT r m) where...



I've looked all over but I can't really find any info on what exactly a multi-parameter constraint like (Foo a b) means. I don't totally understand how e and m work together within the instance head => MonadError e (ReaderT r m).



How do these multi-parameter constraints work? Thanks!










share|improve this question




























    up vote
    1
    down vote

    favorite












    I'm currently reading the paper Monad Transformers Step by Step
    by Martin Grabmüller.



    Theres a part in the paper where he lists off the following instance declaration:



    instance (MonadError e m) => MonadError e (ReaderT r m) where...



    I've looked all over but I can't really find any info on what exactly a multi-parameter constraint like (Foo a b) means. I don't totally understand how e and m work together within the instance head => MonadError e (ReaderT r m).



    How do these multi-parameter constraints work? Thanks!










    share|improve this question


























      up vote
      1
      down vote

      favorite









      up vote
      1
      down vote

      favorite











      I'm currently reading the paper Monad Transformers Step by Step
      by Martin Grabmüller.



      Theres a part in the paper where he lists off the following instance declaration:



      instance (MonadError e m) => MonadError e (ReaderT r m) where...



      I've looked all over but I can't really find any info on what exactly a multi-parameter constraint like (Foo a b) means. I don't totally understand how e and m work together within the instance head => MonadError e (ReaderT r m).



      How do these multi-parameter constraints work? Thanks!










      share|improve this question















      I'm currently reading the paper Monad Transformers Step by Step
      by Martin Grabmüller.



      Theres a part in the paper where he lists off the following instance declaration:



      instance (MonadError e m) => MonadError e (ReaderT r m) where...



      I've looked all over but I can't really find any info on what exactly a multi-parameter constraint like (Foo a b) means. I don't totally understand how e and m work together within the instance head => MonadError e (ReaderT r m).



      How do these multi-parameter constraints work? Thanks!







      haskell typeclass






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 11 at 2:07









      chepner

      238k29223318




      238k29223318










      asked Nov 10 at 18:46









      Vance Palacio

      356311




      356311
























          1 Answer
          1






          active

          oldest

          votes

















          up vote
          3
          down vote



          accepted










          Essentially, a constraint like Show a constrains the type variable a to represent a showable type. You seem to understand this.



          A constraint of the form C a b constrains the pair of type variables a and b. Intuitively, this constrains means that there is a relation between such types.



          Consider this fictional class



          class C a b where
          sum :: a -> b -> (Int, b)


          Intuitively, the constraint C a b means that a and b can be summed together (in that order!), and the result of that sum will be a pair (Int, b).



          In your case you are dealing with



          class Monad m => MonadError e m | m -> e where
          throwError :: e -> m a


          Here, MonadError e m expresses the following relation between e and m.





          1. m is a monad


          2. e is a type for which we can convert any value x :: e into throwError x :: m a, for any a. Intuitively, this is an "error" type, representing the nature of some error, and throwError simply includes such value inside the monad

          3. given m, there is only one error type e. In other words, the relation is actually a function. This is expressed through a functional dependency ... | m -> e in the class above.


          The simple version is: MonadError m a means that m is a monad which can express some "error values", of type e.



          For example, if we have MonadError M String available, we can write



          foo :: Int -> M Int
          foo n | n == 0 = throwError "can't handle zero!"
          | otherwise = return (100 `div` n)





          share|improve this answer





















            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














             

            draft saved


            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53242275%2fmulti-parameter-context-constraints-in-haskell%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            3
            down vote



            accepted










            Essentially, a constraint like Show a constrains the type variable a to represent a showable type. You seem to understand this.



            A constraint of the form C a b constrains the pair of type variables a and b. Intuitively, this constrains means that there is a relation between such types.



            Consider this fictional class



            class C a b where
            sum :: a -> b -> (Int, b)


            Intuitively, the constraint C a b means that a and b can be summed together (in that order!), and the result of that sum will be a pair (Int, b).



            In your case you are dealing with



            class Monad m => MonadError e m | m -> e where
            throwError :: e -> m a


            Here, MonadError e m expresses the following relation between e and m.





            1. m is a monad


            2. e is a type for which we can convert any value x :: e into throwError x :: m a, for any a. Intuitively, this is an "error" type, representing the nature of some error, and throwError simply includes such value inside the monad

            3. given m, there is only one error type e. In other words, the relation is actually a function. This is expressed through a functional dependency ... | m -> e in the class above.


            The simple version is: MonadError m a means that m is a monad which can express some "error values", of type e.



            For example, if we have MonadError M String available, we can write



            foo :: Int -> M Int
            foo n | n == 0 = throwError "can't handle zero!"
            | otherwise = return (100 `div` n)





            share|improve this answer

























              up vote
              3
              down vote



              accepted










              Essentially, a constraint like Show a constrains the type variable a to represent a showable type. You seem to understand this.



              A constraint of the form C a b constrains the pair of type variables a and b. Intuitively, this constrains means that there is a relation between such types.



              Consider this fictional class



              class C a b where
              sum :: a -> b -> (Int, b)


              Intuitively, the constraint C a b means that a and b can be summed together (in that order!), and the result of that sum will be a pair (Int, b).



              In your case you are dealing with



              class Monad m => MonadError e m | m -> e where
              throwError :: e -> m a


              Here, MonadError e m expresses the following relation between e and m.





              1. m is a monad


              2. e is a type for which we can convert any value x :: e into throwError x :: m a, for any a. Intuitively, this is an "error" type, representing the nature of some error, and throwError simply includes such value inside the monad

              3. given m, there is only one error type e. In other words, the relation is actually a function. This is expressed through a functional dependency ... | m -> e in the class above.


              The simple version is: MonadError m a means that m is a monad which can express some "error values", of type e.



              For example, if we have MonadError M String available, we can write



              foo :: Int -> M Int
              foo n | n == 0 = throwError "can't handle zero!"
              | otherwise = return (100 `div` n)





              share|improve this answer























                up vote
                3
                down vote



                accepted







                up vote
                3
                down vote



                accepted






                Essentially, a constraint like Show a constrains the type variable a to represent a showable type. You seem to understand this.



                A constraint of the form C a b constrains the pair of type variables a and b. Intuitively, this constrains means that there is a relation between such types.



                Consider this fictional class



                class C a b where
                sum :: a -> b -> (Int, b)


                Intuitively, the constraint C a b means that a and b can be summed together (in that order!), and the result of that sum will be a pair (Int, b).



                In your case you are dealing with



                class Monad m => MonadError e m | m -> e where
                throwError :: e -> m a


                Here, MonadError e m expresses the following relation between e and m.





                1. m is a monad


                2. e is a type for which we can convert any value x :: e into throwError x :: m a, for any a. Intuitively, this is an "error" type, representing the nature of some error, and throwError simply includes such value inside the monad

                3. given m, there is only one error type e. In other words, the relation is actually a function. This is expressed through a functional dependency ... | m -> e in the class above.


                The simple version is: MonadError m a means that m is a monad which can express some "error values", of type e.



                For example, if we have MonadError M String available, we can write



                foo :: Int -> M Int
                foo n | n == 0 = throwError "can't handle zero!"
                | otherwise = return (100 `div` n)





                share|improve this answer












                Essentially, a constraint like Show a constrains the type variable a to represent a showable type. You seem to understand this.



                A constraint of the form C a b constrains the pair of type variables a and b. Intuitively, this constrains means that there is a relation between such types.



                Consider this fictional class



                class C a b where
                sum :: a -> b -> (Int, b)


                Intuitively, the constraint C a b means that a and b can be summed together (in that order!), and the result of that sum will be a pair (Int, b).



                In your case you are dealing with



                class Monad m => MonadError e m | m -> e where
                throwError :: e -> m a


                Here, MonadError e m expresses the following relation between e and m.





                1. m is a monad


                2. e is a type for which we can convert any value x :: e into throwError x :: m a, for any a. Intuitively, this is an "error" type, representing the nature of some error, and throwError simply includes such value inside the monad

                3. given m, there is only one error type e. In other words, the relation is actually a function. This is expressed through a functional dependency ... | m -> e in the class above.


                The simple version is: MonadError m a means that m is a monad which can express some "error values", of type e.



                For example, if we have MonadError M String available, we can write



                foo :: Int -> M Int
                foo n | n == 0 = throwError "can't handle zero!"
                | otherwise = return (100 `div` n)






                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 10 at 19:06









                chi

                71.6k279132




                71.6k279132






























                     

                    draft saved


                    draft discarded



















































                     


                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53242275%2fmulti-parameter-context-constraints-in-haskell%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Florida Star v. B. J. F.

                    Danny Elfman

                    Lugert, Oklahoma