Curious about why get in StateT monad transformer returns a instead of (a, s)How does this State monad code works?Haskell Monad Transformer Stack and Type Signatureshow can I implement this monad transformer with a continuation?How do I actually execute a StateT monad along with IO?Wadler's paper: How is a tuple a function?StateT and non-determinism monad: a simple exampleWhy do we need monads?Using liftIO and monad transformers, why is the type of a bound variable IO List instead of List?Is it possible to use IO inside State monad, without using StateT and STHaskell - no output from within StateT monadBacktrack over underlying monad in Monad Transformer

What can I do with a research project that is my university’s intellectual property?

When to remove insignificant variables?

Has there been any indication at all that further negotiation between the UK and EU is possible?

JSON selector class in Python

What reason would an alien civilization have for building a Dyson Sphere (or Swarm) if cheap Nuclear fusion is available?

Why did pressing the joystick button spit out keypresses?

How is hair tissue mineral analysis performed?

What does the hyphen "-" mean in "tar xzf -"?

Do I have any obligations to my PhD supervisor's requests after I have graduated?

Should I prioritize my 401k over my student loans?

What is "industrial ethernet"?

How long would it take to cross the Channel in 1890's?

Explain why a line can never intersect a plane in exactly two points.

Did the CIA blow up a Siberian pipeline in 1982?

Output of "$OSTYPE:6" on old releases of Mac OS X

How would modern naval warfare have to have developed differently for battleships to still be relevant in the 21st century?

How does a blind passenger not die, if driver becomes unconscious

Can there be an UN resolution to remove a country from the UNSC?

Why does the Saturn V have standalone inter-stage rings?

How much will studying magic in an academy cost?

How do I set an alias to a terminal line?

Unusual mail headers, evidence of an attempted attack. Have I been pwned?

How to draw this center trajectory of rolling ball?

Are all instances of trolls turning to stone ultimately references back to Tolkien?



Curious about why get in StateT monad transformer returns a instead of (a, s)


How does this State monad code works?Haskell Monad Transformer Stack and Type Signatureshow can I implement this monad transformer with a continuation?How do I actually execute a StateT monad along with IO?Wadler's paper: How is a tuple a function?StateT and non-determinism monad: a simple exampleWhy do we need monads?Using liftIO and monad transformers, why is the type of a bound variable IO List instead of List?Is it possible to use IO inside State monad, without using StateT and STHaskell - no output from within StateT monadBacktrack over underlying monad in Monad Transformer






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








2















I was reading the StateT monad transformer's source, as it reads like this:



get :: (Monad m) => StateT s m s
get = state $ s -> (s, s)


I expanded the above code by switching out state and got this, but still fail to see why it's not returning a tuple.



a <- StateT (return . ( s -> (s, s)))


From the code above it seemed get returns a tuple (s, s), which looked fine, but I'm wondering why when using it, get returned an Int, instead of (Int, Int)?



I traced a lot of source code trying to find when or what changed it but to no avail.



w :: StateT Int IO String
w = do
a <- get
liftIO $ print a -- 2, but why? shouldn't this be (2, 2) instead?
return $ show a

result = runStateT w 2 -- ("2",2)










share|improve this question
























  • get returns a value of type (StateT Int IO) String (I've put the parentheses in to be more explicit, they are implied anyway), so using the <- notation to "extract the underlying value", a is simply a String.

    – Robin Zigmond
    Mar 25 at 8:50






  • 3





    @DonKlein No, get doesn't return anything. It is a value that wraps a function that returns a tuple. Its monad instance defines >>= to pass part of that return value, once it actually gets called via runState(T), as the argument to the next function.

    – chepner
    Mar 25 at 12:09






  • 1





    see the k a in the last line of >>= implementation there, runStateT (k a) s'? that's what it means that only the part of the tuple - i.e. its fst field - is passed along as the "returned value" from a previous computation step into the next computation step, while the s' in ( a , s') is tagging along as part of the stateful computation "pipeline". So we "compute" the a "value", and s "state" is maintained on the side for us.

    – Will Ness
    Mar 25 at 12:37







  • 1





    see e.g. this for some illuminating (hopefully) re-writes in the answers. (disclaimer: one of them is by me). it's for simple State (no transformers) so should be simpler to follow. transformers just juggle the additional monads around, but the essence of state passing is the same.

    – Will Ness
    Mar 25 at 13:18







  • 1





    Don't put an answer in the question itself. You can post an answer to your own question if you fee the need.

    – chepner
    Mar 25 at 14:07

















2















I was reading the StateT monad transformer's source, as it reads like this:



get :: (Monad m) => StateT s m s
get = state $ s -> (s, s)


I expanded the above code by switching out state and got this, but still fail to see why it's not returning a tuple.



a <- StateT (return . ( s -> (s, s)))


From the code above it seemed get returns a tuple (s, s), which looked fine, but I'm wondering why when using it, get returned an Int, instead of (Int, Int)?



I traced a lot of source code trying to find when or what changed it but to no avail.



w :: StateT Int IO String
w = do
a <- get
liftIO $ print a -- 2, but why? shouldn't this be (2, 2) instead?
return $ show a

result = runStateT w 2 -- ("2",2)










share|improve this question
























  • get returns a value of type (StateT Int IO) String (I've put the parentheses in to be more explicit, they are implied anyway), so using the <- notation to "extract the underlying value", a is simply a String.

    – Robin Zigmond
    Mar 25 at 8:50






  • 3





    @DonKlein No, get doesn't return anything. It is a value that wraps a function that returns a tuple. Its monad instance defines >>= to pass part of that return value, once it actually gets called via runState(T), as the argument to the next function.

    – chepner
    Mar 25 at 12:09






  • 1





    see the k a in the last line of >>= implementation there, runStateT (k a) s'? that's what it means that only the part of the tuple - i.e. its fst field - is passed along as the "returned value" from a previous computation step into the next computation step, while the s' in ( a , s') is tagging along as part of the stateful computation "pipeline". So we "compute" the a "value", and s "state" is maintained on the side for us.

    – Will Ness
    Mar 25 at 12:37







  • 1





    see e.g. this for some illuminating (hopefully) re-writes in the answers. (disclaimer: one of them is by me). it's for simple State (no transformers) so should be simpler to follow. transformers just juggle the additional monads around, but the essence of state passing is the same.

    – Will Ness
    Mar 25 at 13:18







  • 1





    Don't put an answer in the question itself. You can post an answer to your own question if you fee the need.

    – chepner
    Mar 25 at 14:07













2












2








2


1






I was reading the StateT monad transformer's source, as it reads like this:



get :: (Monad m) => StateT s m s
get = state $ s -> (s, s)


I expanded the above code by switching out state and got this, but still fail to see why it's not returning a tuple.



a <- StateT (return . ( s -> (s, s)))


From the code above it seemed get returns a tuple (s, s), which looked fine, but I'm wondering why when using it, get returned an Int, instead of (Int, Int)?



I traced a lot of source code trying to find when or what changed it but to no avail.



w :: StateT Int IO String
w = do
a <- get
liftIO $ print a -- 2, but why? shouldn't this be (2, 2) instead?
return $ show a

result = runStateT w 2 -- ("2",2)










share|improve this question
















I was reading the StateT monad transformer's source, as it reads like this:



get :: (Monad m) => StateT s m s
get = state $ s -> (s, s)


I expanded the above code by switching out state and got this, but still fail to see why it's not returning a tuple.



a <- StateT (return . ( s -> (s, s)))


From the code above it seemed get returns a tuple (s, s), which looked fine, but I'm wondering why when using it, get returned an Int, instead of (Int, Int)?



I traced a lot of source code trying to find when or what changed it but to no avail.



w :: StateT Int IO String
w = do
a <- get
liftIO $ print a -- 2, but why? shouldn't this be (2, 2) instead?
return $ show a

result = runStateT w 2 -- ("2",2)







haskell






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 25 at 14:08









chepner

274k40266359




274k40266359










asked Mar 25 at 8:47









Don KleinDon Klein

715




715












  • get returns a value of type (StateT Int IO) String (I've put the parentheses in to be more explicit, they are implied anyway), so using the <- notation to "extract the underlying value", a is simply a String.

    – Robin Zigmond
    Mar 25 at 8:50






  • 3





    @DonKlein No, get doesn't return anything. It is a value that wraps a function that returns a tuple. Its monad instance defines >>= to pass part of that return value, once it actually gets called via runState(T), as the argument to the next function.

    – chepner
    Mar 25 at 12:09






  • 1





    see the k a in the last line of >>= implementation there, runStateT (k a) s'? that's what it means that only the part of the tuple - i.e. its fst field - is passed along as the "returned value" from a previous computation step into the next computation step, while the s' in ( a , s') is tagging along as part of the stateful computation "pipeline". So we "compute" the a "value", and s "state" is maintained on the side for us.

    – Will Ness
    Mar 25 at 12:37







  • 1





    see e.g. this for some illuminating (hopefully) re-writes in the answers. (disclaimer: one of them is by me). it's for simple State (no transformers) so should be simpler to follow. transformers just juggle the additional monads around, but the essence of state passing is the same.

    – Will Ness
    Mar 25 at 13:18







  • 1





    Don't put an answer in the question itself. You can post an answer to your own question if you fee the need.

    – chepner
    Mar 25 at 14:07

















  • get returns a value of type (StateT Int IO) String (I've put the parentheses in to be more explicit, they are implied anyway), so using the <- notation to "extract the underlying value", a is simply a String.

    – Robin Zigmond
    Mar 25 at 8:50






  • 3





    @DonKlein No, get doesn't return anything. It is a value that wraps a function that returns a tuple. Its monad instance defines >>= to pass part of that return value, once it actually gets called via runState(T), as the argument to the next function.

    – chepner
    Mar 25 at 12:09






  • 1





    see the k a in the last line of >>= implementation there, runStateT (k a) s'? that's what it means that only the part of the tuple - i.e. its fst field - is passed along as the "returned value" from a previous computation step into the next computation step, while the s' in ( a , s') is tagging along as part of the stateful computation "pipeline". So we "compute" the a "value", and s "state" is maintained on the side for us.

    – Will Ness
    Mar 25 at 12:37







  • 1





    see e.g. this for some illuminating (hopefully) re-writes in the answers. (disclaimer: one of them is by me). it's for simple State (no transformers) so should be simpler to follow. transformers just juggle the additional monads around, but the essence of state passing is the same.

    – Will Ness
    Mar 25 at 13:18







  • 1





    Don't put an answer in the question itself. You can post an answer to your own question if you fee the need.

    – chepner
    Mar 25 at 14:07
















get returns a value of type (StateT Int IO) String (I've put the parentheses in to be more explicit, they are implied anyway), so using the <- notation to "extract the underlying value", a is simply a String.

– Robin Zigmond
Mar 25 at 8:50





get returns a value of type (StateT Int IO) String (I've put the parentheses in to be more explicit, they are implied anyway), so using the <- notation to "extract the underlying value", a is simply a String.

– Robin Zigmond
Mar 25 at 8:50




3




3





@DonKlein No, get doesn't return anything. It is a value that wraps a function that returns a tuple. Its monad instance defines >>= to pass part of that return value, once it actually gets called via runState(T), as the argument to the next function.

– chepner
Mar 25 at 12:09





@DonKlein No, get doesn't return anything. It is a value that wraps a function that returns a tuple. Its monad instance defines >>= to pass part of that return value, once it actually gets called via runState(T), as the argument to the next function.

– chepner
Mar 25 at 12:09




1




1





see the k a in the last line of >>= implementation there, runStateT (k a) s'? that's what it means that only the part of the tuple - i.e. its fst field - is passed along as the "returned value" from a previous computation step into the next computation step, while the s' in ( a , s') is tagging along as part of the stateful computation "pipeline". So we "compute" the a "value", and s "state" is maintained on the side for us.

– Will Ness
Mar 25 at 12:37






see the k a in the last line of >>= implementation there, runStateT (k a) s'? that's what it means that only the part of the tuple - i.e. its fst field - is passed along as the "returned value" from a previous computation step into the next computation step, while the s' in ( a , s') is tagging along as part of the stateful computation "pipeline". So we "compute" the a "value", and s "state" is maintained on the side for us.

– Will Ness
Mar 25 at 12:37





1




1





see e.g. this for some illuminating (hopefully) re-writes in the answers. (disclaimer: one of them is by me). it's for simple State (no transformers) so should be simpler to follow. transformers just juggle the additional monads around, but the essence of state passing is the same.

– Will Ness
Mar 25 at 13:18






see e.g. this for some illuminating (hopefully) re-writes in the answers. (disclaimer: one of them is by me). it's for simple State (no transformers) so should be simpler to follow. transformers just juggle the additional monads around, but the essence of state passing is the same.

– Will Ness
Mar 25 at 13:18





1




1





Don't put an answer in the question itself. You can post an answer to your own question if you fee the need.

– chepner
Mar 25 at 14:07





Don't put an answer in the question itself. You can post an answer to your own question if you fee the need.

– chepner
Mar 25 at 14:07












1 Answer
1






active

oldest

votes


















3














A value of type StateT s m a, modulo newtype wrappers, is a function with type s -> m (a, s).



The function (return . ( s -> (s, s))) has type s -> m (s, s), hence once it is wrapped by the StateT constructor becomes a value of type StateT s m s.



Note that a value of type StateT s m (s, s) would instead involve a function of type s -> m (s, (s, s)) which is not what we are using here.



Your confusion seem to arise from the "other" s in m (s, s), which does not contribute to x when we run x <- get. To understand why, it's useful to think to think to what a stateful computation performs:



  • First, we read the old state of type s. This is the s -> .. part in the type s -> m (a, s).

  • Then, we run some action in the monad m. This is the .. -> m .. part in the type s -> m (a, s).

    • The monadic action returns a new state, to replace the old one. This is the .. -> .. (.., s) part in the type s -> m (a, s).

    • Finally, monadic action also returns a value, of a possibly different type a. This the .. -> .. (a, ..) part in the type s -> m (a, s).


Running x <- action handles all these types automatically for us, and lets x to have the result type a, only.



Concretely, consider this imperative pseudo-code:



global n: int

def foo():
if n > 5:
print ">5"
n = 8
return "hello"
else:
print "not >5"
n = 10
return "greetings"


In an imperative language, we would type this as foo(): string, since it returns a string, disregarding its side effects to the global n: int and the printed messages.



In Haskell, we would instead model that using a more precise type like



Int -> IO (String, Int)
^-- the old n
^-- the printed stuff
^-- the returned string
^-- the new n


Again, running x <- foo() we want x: string, not x: (string, int), following what would happen in an imperative language.



If instead we had a function



global n: int

def bar():
old_n = n
n = n + 5
return old_n


we would use the type



Int -> IO (Int, Int)


since the returned value is an Int now. Similarly,



global n: int

def get():
return n


could use the same type



Int -> IO (Int, Int)


Now, one might argue that the second Int is not strictly necessary here, since get() is not really producing a new state -- it's not changing the value of n. Still, it's convenient to use a type of the same form, s -> m (a, s), as any function which could change the state. This is so that it can be used together with any other function having a similar type.






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',
    autoActivateHeartbeat: false,
    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%2f55334033%2fcurious-about-why-get-in-statet-monad-transformer-returns-a-instead-of-a-s%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









    3














    A value of type StateT s m a, modulo newtype wrappers, is a function with type s -> m (a, s).



    The function (return . ( s -> (s, s))) has type s -> m (s, s), hence once it is wrapped by the StateT constructor becomes a value of type StateT s m s.



    Note that a value of type StateT s m (s, s) would instead involve a function of type s -> m (s, (s, s)) which is not what we are using here.



    Your confusion seem to arise from the "other" s in m (s, s), which does not contribute to x when we run x <- get. To understand why, it's useful to think to think to what a stateful computation performs:



    • First, we read the old state of type s. This is the s -> .. part in the type s -> m (a, s).

    • Then, we run some action in the monad m. This is the .. -> m .. part in the type s -> m (a, s).

      • The monadic action returns a new state, to replace the old one. This is the .. -> .. (.., s) part in the type s -> m (a, s).

      • Finally, monadic action also returns a value, of a possibly different type a. This the .. -> .. (a, ..) part in the type s -> m (a, s).


    Running x <- action handles all these types automatically for us, and lets x to have the result type a, only.



    Concretely, consider this imperative pseudo-code:



    global n: int

    def foo():
    if n > 5:
    print ">5"
    n = 8
    return "hello"
    else:
    print "not >5"
    n = 10
    return "greetings"


    In an imperative language, we would type this as foo(): string, since it returns a string, disregarding its side effects to the global n: int and the printed messages.



    In Haskell, we would instead model that using a more precise type like



    Int -> IO (String, Int)
    ^-- the old n
    ^-- the printed stuff
    ^-- the returned string
    ^-- the new n


    Again, running x <- foo() we want x: string, not x: (string, int), following what would happen in an imperative language.



    If instead we had a function



    global n: int

    def bar():
    old_n = n
    n = n + 5
    return old_n


    we would use the type



    Int -> IO (Int, Int)


    since the returned value is an Int now. Similarly,



    global n: int

    def get():
    return n


    could use the same type



    Int -> IO (Int, Int)


    Now, one might argue that the second Int is not strictly necessary here, since get() is not really producing a new state -- it's not changing the value of n. Still, it's convenient to use a type of the same form, s -> m (a, s), as any function which could change the state. This is so that it can be used together with any other function having a similar type.






    share|improve this answer





























      3














      A value of type StateT s m a, modulo newtype wrappers, is a function with type s -> m (a, s).



      The function (return . ( s -> (s, s))) has type s -> m (s, s), hence once it is wrapped by the StateT constructor becomes a value of type StateT s m s.



      Note that a value of type StateT s m (s, s) would instead involve a function of type s -> m (s, (s, s)) which is not what we are using here.



      Your confusion seem to arise from the "other" s in m (s, s), which does not contribute to x when we run x <- get. To understand why, it's useful to think to think to what a stateful computation performs:



      • First, we read the old state of type s. This is the s -> .. part in the type s -> m (a, s).

      • Then, we run some action in the monad m. This is the .. -> m .. part in the type s -> m (a, s).

        • The monadic action returns a new state, to replace the old one. This is the .. -> .. (.., s) part in the type s -> m (a, s).

        • Finally, monadic action also returns a value, of a possibly different type a. This the .. -> .. (a, ..) part in the type s -> m (a, s).


      Running x <- action handles all these types automatically for us, and lets x to have the result type a, only.



      Concretely, consider this imperative pseudo-code:



      global n: int

      def foo():
      if n > 5:
      print ">5"
      n = 8
      return "hello"
      else:
      print "not >5"
      n = 10
      return "greetings"


      In an imperative language, we would type this as foo(): string, since it returns a string, disregarding its side effects to the global n: int and the printed messages.



      In Haskell, we would instead model that using a more precise type like



      Int -> IO (String, Int)
      ^-- the old n
      ^-- the printed stuff
      ^-- the returned string
      ^-- the new n


      Again, running x <- foo() we want x: string, not x: (string, int), following what would happen in an imperative language.



      If instead we had a function



      global n: int

      def bar():
      old_n = n
      n = n + 5
      return old_n


      we would use the type



      Int -> IO (Int, Int)


      since the returned value is an Int now. Similarly,



      global n: int

      def get():
      return n


      could use the same type



      Int -> IO (Int, Int)


      Now, one might argue that the second Int is not strictly necessary here, since get() is not really producing a new state -- it's not changing the value of n. Still, it's convenient to use a type of the same form, s -> m (a, s), as any function which could change the state. This is so that it can be used together with any other function having a similar type.






      share|improve this answer



























        3












        3








        3







        A value of type StateT s m a, modulo newtype wrappers, is a function with type s -> m (a, s).



        The function (return . ( s -> (s, s))) has type s -> m (s, s), hence once it is wrapped by the StateT constructor becomes a value of type StateT s m s.



        Note that a value of type StateT s m (s, s) would instead involve a function of type s -> m (s, (s, s)) which is not what we are using here.



        Your confusion seem to arise from the "other" s in m (s, s), which does not contribute to x when we run x <- get. To understand why, it's useful to think to think to what a stateful computation performs:



        • First, we read the old state of type s. This is the s -> .. part in the type s -> m (a, s).

        • Then, we run some action in the monad m. This is the .. -> m .. part in the type s -> m (a, s).

          • The monadic action returns a new state, to replace the old one. This is the .. -> .. (.., s) part in the type s -> m (a, s).

          • Finally, monadic action also returns a value, of a possibly different type a. This the .. -> .. (a, ..) part in the type s -> m (a, s).


        Running x <- action handles all these types automatically for us, and lets x to have the result type a, only.



        Concretely, consider this imperative pseudo-code:



        global n: int

        def foo():
        if n > 5:
        print ">5"
        n = 8
        return "hello"
        else:
        print "not >5"
        n = 10
        return "greetings"


        In an imperative language, we would type this as foo(): string, since it returns a string, disregarding its side effects to the global n: int and the printed messages.



        In Haskell, we would instead model that using a more precise type like



        Int -> IO (String, Int)
        ^-- the old n
        ^-- the printed stuff
        ^-- the returned string
        ^-- the new n


        Again, running x <- foo() we want x: string, not x: (string, int), following what would happen in an imperative language.



        If instead we had a function



        global n: int

        def bar():
        old_n = n
        n = n + 5
        return old_n


        we would use the type



        Int -> IO (Int, Int)


        since the returned value is an Int now. Similarly,



        global n: int

        def get():
        return n


        could use the same type



        Int -> IO (Int, Int)


        Now, one might argue that the second Int is not strictly necessary here, since get() is not really producing a new state -- it's not changing the value of n. Still, it's convenient to use a type of the same form, s -> m (a, s), as any function which could change the state. This is so that it can be used together with any other function having a similar type.






        share|improve this answer















        A value of type StateT s m a, modulo newtype wrappers, is a function with type s -> m (a, s).



        The function (return . ( s -> (s, s))) has type s -> m (s, s), hence once it is wrapped by the StateT constructor becomes a value of type StateT s m s.



        Note that a value of type StateT s m (s, s) would instead involve a function of type s -> m (s, (s, s)) which is not what we are using here.



        Your confusion seem to arise from the "other" s in m (s, s), which does not contribute to x when we run x <- get. To understand why, it's useful to think to think to what a stateful computation performs:



        • First, we read the old state of type s. This is the s -> .. part in the type s -> m (a, s).

        • Then, we run some action in the monad m. This is the .. -> m .. part in the type s -> m (a, s).

          • The monadic action returns a new state, to replace the old one. This is the .. -> .. (.., s) part in the type s -> m (a, s).

          • Finally, monadic action also returns a value, of a possibly different type a. This the .. -> .. (a, ..) part in the type s -> m (a, s).


        Running x <- action handles all these types automatically for us, and lets x to have the result type a, only.



        Concretely, consider this imperative pseudo-code:



        global n: int

        def foo():
        if n > 5:
        print ">5"
        n = 8
        return "hello"
        else:
        print "not >5"
        n = 10
        return "greetings"


        In an imperative language, we would type this as foo(): string, since it returns a string, disregarding its side effects to the global n: int and the printed messages.



        In Haskell, we would instead model that using a more precise type like



        Int -> IO (String, Int)
        ^-- the old n
        ^-- the printed stuff
        ^-- the returned string
        ^-- the new n


        Again, running x <- foo() we want x: string, not x: (string, int), following what would happen in an imperative language.



        If instead we had a function



        global n: int

        def bar():
        old_n = n
        n = n + 5
        return old_n


        we would use the type



        Int -> IO (Int, Int)


        since the returned value is an Int now. Similarly,



        global n: int

        def get():
        return n


        could use the same type



        Int -> IO (Int, Int)


        Now, one might argue that the second Int is not strictly necessary here, since get() is not really producing a new state -- it's not changing the value of n. Still, it's convenient to use a type of the same form, s -> m (a, s), as any function which could change the state. This is so that it can be used together with any other function having a similar type.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Mar 25 at 13:12









        Will Ness

        48.3k471131




        48.3k471131










        answered Mar 25 at 12:36









        chichi

        79.6k288151




        79.6k288151





























            draft saved

            draft discarded
















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55334033%2fcurious-about-why-get-in-statet-monad-transformer-returns-a-instead-of-a-s%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

            Kamusi Yaliyomo Aina za kamusi | Muundo wa kamusi | Faida za kamusi | Dhima ya picha katika kamusi | Marejeo | Tazama pia | Viungo vya nje | UrambazajiKuhusu kamusiGo-SwahiliWiki-KamusiKamusi ya Kiswahili na Kiingerezakuihariri na kuongeza habari

            Swift 4 - func physicsWorld not invoked on collision? The Next CEO of Stack OverflowHow to call Objective-C code from Swift#ifdef replacement in the Swift language@selector() in Swift?#pragma mark in Swift?Swift for loop: for index, element in array?dispatch_after - GCD in Swift?Swift Beta performance: sorting arraysSplit a String into an array in Swift?The use of Swift 3 @objc inference in Swift 4 mode is deprecated?How to optimize UITableViewCell, because my UITableView lags

            Access current req object everywhere in Node.js ExpressWhy are global variables considered bad practice? (node.js)Using req & res across functionsHow do I get the path to the current script with Node.js?What is Node.js' Connect, Express and “middleware”?Node.js w/ express error handling in callbackHow to access the GET parameters after “?” in Express?Modify Node.js req object parametersAccess “app” variable inside of ExpressJS/ConnectJS middleware?Node.js Express app - request objectAngular Http Module considered middleware?Session variables in ExpressJSAdd properties to the req object in expressjs with Typescript