What is the difference between different orderings of the same monad transformers?

I am attempting to define an API to express a particular type of procedure in my program.

newtype Procedure a = { runProcedure :: ? }

There is state, consisting of a mapping of IDs to records:

type ID = Int
data Record = { ... }
type ProcedureState = Map ID Record

There are three basic operations:

-- Declare the current procedure invalid and bail (similar to some definitions of fail for class Monad)
abort :: Procedure ()
-- Get a record from the shared state; abort if the record does not exist.
retrieve :: ID -> Procedure Record
-- Store (or overwrite) a record in the shared state.
store :: ID -> Record -> Procedure ()

I have a few goals with these operations:

  • Procedures can make assumptions (unlike a raw Map.lookup call) about which records are available, and if any of their assumptions are wrong, the Procedure as a whole returns failure.
  • A series of Procedures can be chained together using <|> (from class Alternative) in order to fall back to Procedures that make different assumptions. (Similar to STM's orElse)

Given these goals, I believe I want some combination of the State and Maybe monads.

-- Which to choose?
type Procedure a = StateT ProcedureState Maybe a
type Procedure a = MaybeT (State ProcedureState) a

I can't figure out how the two orderings of Maybe and State will behave differently. Can anyone explain the difference in behavior between the two orderings?

Also, if you see a problem with my original thinking (perhaps I am over-engineering), feel free to point it out.

Conclusion: All three answers were helpful, but there was one common idea that helped me decide which ordering I wanted. By looking at the return type of runMaybeT/runStateT, it was easy to see which combination had the behavior I was looking for. (In my case, I want the return type Maybe (ProcedureState, a)).

Edit: I originally got the cases backwards. Fixed now.

The difference between orderings of monad transformer stacks really only matters when you're peeling off layers of the stack.

type Procedure a = MaybeT (State ProcedureState) a

In this case, you first run the MaybeT, which results in a stateful computation which returns a Maybe a.

type Procedure a = StateT ProcedureState Maybe a

Here the StateT is the outer monad, which means that after running the StateT with an initial state, you'll be given a Maybe (a, ProcedureState). That is, the computation may have succeeded, or may not have.

So which you choose depends upon how you want to handle partial computations. With MaybeT on the outside, you'll always get some sort of returned state regardless of the computation's success, which may or may not be useful. With StateT on the outside, you guarantee that all stateful transactions are valid. From what you describe, I would probably use the StateT variant myself, but I expect either could work.

The only rule for monad transformer ordering is that if IO (or another non-transformer monad) is involved, it must be the bottom of the stack. Typically people will use ErrorT as the next lowest level if it's required.

Chapter 18. Monad transformers, By convention, the transformer version of a monad has the same name, with a T stuck The difference arises when we try to construct another type from one of these. Modify the App type synonym to swap the order of ReaderT and WriterT. Conclusion. A functor is a data type that implements the Functor typeclass. An applicative is a data type that implements the Applicative typeclass. A monad is a data type that implements the Monad typeclass. A Maybe implements all three, so it is a functor, an applicative, and a monad.

Haskell/Monad transformers, In this tutorial, we describe how to use monad transformers in order to incrementally add library of different monads and types and functions for combining these The definition of eval0 could be shortened a little bit, for example, the let expression in the The running function is extended in the same way as earlier. When that happens you'll be able to import monads-fd and transformers and get (almost) the same interface, with the exception that State, etc. will be an alias for StateT. So I'd write to mtl , but not rely on the fact that State, Reader, etc. are currently data as they will be replaced with type s.

[PDF] Monad Transformers Step by Step, You should download the lhs version of this module and replace all parts marked The type Either s is a monad, with a very similar definition to that of Maybe . transformer for the state monad, following more or less the same recipe as we did for We can also order the transformations differently (which can have different  Note that this will be the timing of the expression as evaluated in the interpreter, without optimisation, so it won’t necessarily be an accurate measure of how long things take, or even which of two versions of the same code will be faster, in actual compiled code. For that, take a look at the criterion benchmarking library.

You'll be able to answer the question yourself if you try to write "run" functions for both versions - I don't have MTL + transformers installed so I'm not able to do it myself. One will return (Maybe a,state) the other Maybe (a,state).

Edit - I've truncated my response as it adds detail which might be confusing. John's answer hits the nail on the head.

Monad Transformers, This has nothing to do with a monad transformer, just review. As a made up example: let's write a sum function that adds up all numbers until the first If we had to write a productTillNegative , the body would be almost exactly the same. You should convince yourself that this definition is isomorphic to the previous  Motivated by the post of /u/saosebastiao I will be covering an example of how to use Eff as a replacement for monad transformers, I will be using Cats for our monad transformers, and Eff for the Eff monad. I will use the following as our running example for the different approaches: We will create a method that gets the state of an Int variable.

Monad Transformers, In a sense this is composable – certainly all programs in one monad compose together – but it's composable in the same sense that to the underlying definition of M . If I later decide I want to layer in the chance of failure (perhaps with functional dependencies. mtl makes use of functional dependencies in order to retain  Center tap transformer gives you different range of voltage at secondary side whenever required to operate at different loading condition but normal transformer gives you same fix voltage at secondary side irrespective of loading condition. center

Monad transformers, free monads, mtl, laws and a new approach, If we can write instances of that typeclass for various transformers, we can of the entire monad, these functions need to be inductive in the same way. Consider, for a moment, the difference between these types. Both these stacks contain StateT and ExceptT , but they are layered in a different order. Low voltage transformers supply different levels of current when the line voltage on the input side fluctuates or when there are power surges. LEDs are very sensitive to overcurrents and can rapidly overheat and burn out during current fluctuations. LED drivers regulate the current to make sure it stays below the danger values for the LED. Even

Demystifying `MonadBaseControl`, The type R captures all this information : empty : : PQ a insert : : Ord a = > a - > PQ a Interface for priority queues . newtype OL e a instance Monad ( OL e ) This relies The key operation is order , that checks the relative position of two records , and This monad is an instance of the environment monad transformer [ 10 ]  What is the difference between a regular transformer and an isolation transformer? What is an autotransformer? Schneider Electric USA Website. LV Transformers .

Proceedings of the Seventh ACM SIGPLAN International Conference on , All About Monads is a tutorial on monads and monad transformers and a 2.3.1 Overview; 2.3.2 Motivation; 2.3.3 Definition; 2.3.4 Example 11 that takes it arguments in the opposite order to the standard binding function. What is the difference between ONAN and KNAN transformer in Oil Distribution Transformers? Published date: 25 January 2018 The designation of cooling types of the oil distribution transformers depend on the fire point of the oil being used in the transformer.

Comments
  • If you run the two monad transformer stacks through lambdabot's @unmtl then the first becomes ProcedureState -> (Maybe a, ProcedureState) and the second ProcedureState -> Maybe (a, ProcedureState), so I think you've gotten them backwards. The types of the run...T functions are confusing!
  • @Reid Barton, thanks much. You're completely correct that I got them backwards. Edited to correct.
  • Excelent answer.