<p>I was able to figure this out. My <code>IfElse</code> case was incorrect. It should be:</p>
<pre><code>run (IfZero c1 c2) xs   = case xs of 
                            (0:ys) -&gt; run c1 ys
                            (_:ys) -&gt; run c2 ys 
                            otherwise -&gt; Nothing 
</code></pre>

CC BY-SA 4.0
2023-06-24T22:09:56.320Z
2023-06-24T22:09:56.320Z
tyvan266
<p>I'm working through IOHK Haskell course from 2020, and I'm stuck on problem assignment W3.1, full description linked here:</p>
<p><a href="https://github.com/iohkedu/w03" rel="nofollow noreferrer">https://github.com/iohkedu/w03</a></p>
<p>I do not understand how the <code>instructions</code> type is supposed to be ordered and evaluated. My code attempt introduces an extra parameter for initial stack, because otherwise I can't conceptualize how <code>IfZero</code> would be able to &quot;look at the stack&quot;. Then my code attempt is</p>
<pre><code>
run :: Instructions -&gt; [Int] -&gt; Maybe [Int]  
run (Push n code) xs    = run code (n:xs) 
run (Pop code) (x:xs)   = run code xs
run (Add code) xs       = case xs of 
                            (x:y:ys) -&gt; run code (x+y:ys)
                            otherwise -&gt; Nothing
run (Mul code) xs       = case xs of 
                            (x:y:ys) -&gt; run code (x*y:ys)    
                            otherwise -&gt; Nothing    
run (Dup code) xs       = case xs of 
                            (x:ys) -&gt; run code (x:x:ys)
                            otherwise -&gt; Nothing
run (Swap code) xs      = case xs of  
                            (x:y:ys) -&gt; run code (y:x:ys)
                            otherwise -&gt; Nothing 
run (Over code) xs      = case xs of 
                            (x:y:ys) -&gt; run code (y:x:y:ys)
                            otherwise -&gt; Nothing 
run (Neg code) xs       = case xs of
                            (x:ys) -&gt; run code (-x:ys)
                            otherwise -&gt; Nothing 
run (IfZero c1 c2) xs   = case xs of 
                            (0:ys) -&gt; run c1 xs 
                            (_:ys) -&gt; run c2 xs 
                            otherwise -&gt; Nothing    
run (Loop f) xs         = run (f (Loop f)) xs                                                                
run Halt xs             = Just xs 

</code></pre>
<p>But when run on their example <code>fact5</code> instructions, my <code>run fact5 []</code> gives me the wrong output of <code>Just [0,0,1,4,9,16,25,1]</code>. I'm unable to even trace out on pen and paper what their <code>fact5</code> is supposed to be doing ...</p>
<pre><code>fact5 :: Instructions
fact5 =
  Push 5 $
  Push 1 $
  Swap $
  Loop $ \ loop -&gt;
  Dup $
  IfZero (Pop $ Halt) $
  Swap $
  Over $
  Mul $
  Swap $
  Push 1 $
  Neg $
  Add $
  loop
</code></pre>
<p>appreciate any help</p>

<haskell>
A Simple stack language
# A Simple stack language

(Asked by: username_0 on 2023-05-31)

I'm working through IOHK Haskell course from 2020, and I'm stuck on problem assignment W3.1, full description linked here:
https://github.com/iohkedu/w03
I do not understand how the instructions type is supposed to be ordered and evaluated. My code attempt introduces an extra parameter for initial stack, because otherwise I can't conceptualize how IfZero would be able to "look at the stack". Then my code attempt is

run :: Instructions -> [Int] -> Maybe [Int]  
run (Push n code) xs    = run code (n:xs) 
run (Pop code) (x:xs)   = run code xs
run (Add code) xs       = case xs of 
                            (x:y:ys) -> run code (x+y:ys)
                            otherwise -> Nothing
run (Mul code) xs       = case xs of 
                            (x:y:ys) -> run code (x*y:ys)    
                            otherwise -> Nothing    
run (Dup code) xs       = case xs of 
                            (x:ys) -> run code (x:x:ys)
                            otherwise -> Nothing
run (Swap code) xs      = case xs of  
                            (x:y:ys) -> run code (y:x:ys)
                            otherwise -> Nothing 
run (Over code) xs      = case xs of 
                            (x:y:ys) -> run code (y:x:y:ys)
                            otherwise -> Nothing 
run (Neg code) xs       = case xs of
                            (x:ys) -> run code (-x:ys)
                            otherwise -> Nothing 
run (IfZero c1 c2) xs   = case xs of 
                            (0:ys) -> run c1 xs 
                            (_:ys) -> run c2 xs 
                            otherwise -> Nothing    
run (Loop f) xs         = run (f (Loop f)) xs                                                                
run Halt xs             = Just xs 


But when run on their example fact5 instructions, my run fact5 [] gives me the wrong output of Just [0,0,1,4,9,16,25,1]. I'm unable to even trace out on pen and paper what their fact5 is supposed to be doing ...
fact5 :: Instructions
fact5 =
  Push 5 $
  Push 1 $
  Swap $
  Loop $ \ loop ->
  Dup $
  IfZero (Pop $ Halt) $
  Swap $
  Over $
  Mul $
  Swap $
  Push 1 $
  Neg $
  Add $
  loop

appreciate any help

**Tags:** haskell

---

## 1 answers

### Answer by username_0 on 2023-06-24. Score: 0 | Accepted answer

I was able to figure this out. My IfElse case was incorrect. It should be:
run (IfZero c1 c2) xs   = case xs of 
                            (0:ys) -> run c1 ys
                            (_:ys) -> run c2 ys 
                            otherwise -> Nothing


---

