Note that there are some explanatory texts on larger screens.

plurals
  1. PODo notation without monads: possible?
    text
    copied!<p>I have a stateful type with the <code>&gt;&gt;</code> and <code>&gt;&gt;=</code> operators, which is nearly a monad. The intended use is to generate code for another language, and having the do-notation available will be very appropriate.</p> <p>However, there is no well-defined return function, as values are only supposed to be produced along with side-effects. So, if I fake a return function, the return function should return an error only, and it breaks the monad laws. ( I.e. it is never valid to use a return function. )</p> <p>What I observe is that the do-notation only sugars two operators, the <code>&gt;&gt;</code> and <code>&gt;&gt;=</code> operators.</p> <p>Is there a way to retain something like the do notation for only those 2 operators, or something as clean as it, but without making a monad?</p> <p>NOTE: Below the line are details that are not necessary for the question in the title. It's the context for why I asked the question, replies to which I'm interested in. Others who browse this topic would probably prefer to ignore it.</p> <hr> <p>CORRECTION: I'm not generating code into an imperative language, although it shouldn't matter. I'm generating code into Javascript.</p> <p>CLARIFICATION (in response to bdonlan): My type is (m a), which carries a state (which is the code to be generated given various parameters, similar to the state monad) and will return a value (the variable names in the generated code, with a haskell type attached). Thus, there shouldn't be a way to return values, which are associated with variable names, without generating code that defines the variable names. * This is solely due to my design, which might be inferior to others which I have not thought of.</p> <p>In response to the responses: There seems to be two kinds of responses to this. First, is whether it is indeed possible, and perhaps the best way to go about using the do notation. The second is on whether it is better to use a monad, and define a return (or whether it even makes sense to not do so - perhaps at a later point in time, I would find that a return is required).</p> <p>Example of what I would be doing:</p> <pre><code>data JsState = JsState { code :: String , vidCount :: Int } -- vidCount is for generating unique variable names newtype JsStmt = JsStmt ( JsState -&gt; JsState ) newtype JsMonad a = JsMonad ( JsState -&gt; ( a , JsState ) ) def :: (JsValue a) =&gt; a -&gt; JsMonad a -- Outputs "var " ++ toUniqueVarName vidCount ++ " = " toCode a ++ ";" -- Returns JsMonad with the variable name as the value, -- with a type attached, and the JsState's vidCount is incremented by 1. alertJsInt :: JsIntE -&gt; JsMonad () -- Outputs something like "alert(" ++ toCode JsIntE ++ ");" do x &lt;- def $ JsIntL 2 y &lt;- def $ JsIntL 4 alertJsInt (x + y) </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload