# Return in while loop is not expected behaviour

**URL:** <https://discuss.moonbitlang.com/t/return-in-while-loop-is-not-expected-behaviour/161>\
**Category:** Development\
**Created:** [February 20, 2024, 2:07am UTC](https://discuss.moonbitlang.com/t/return-in-while-loop-is-not-expected-behaviour/161 "2024-02-20T02:07:19Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Mng12345](https://discuss.moonbitlang.com/user_avatar/discuss.moonbitlang.com/mng12345/32/6_2.png) [@Mng12345](https://discuss.moonbitlang.com/u/Mng12345)\
**Post date:** [February 20, 2024, 2:07am UTC](https://discuss.moonbitlang.com/t/return-in-while-loop-is-not-expected-behaviour/161/1 "2024-02-20T02:07:19Z")

</div>

[playground](https://try.moonbitlang.com/#d834ecab)

```auto
type ParsedValue[V] Result[(V, String), String]

struct Lexer[V] {
  parse: (String) -> ParsedValue[V]
}

fn Lexer::and[V1, V2](self: Lexer[V1], lexer2: Lexer[V2]) -> Lexer[(V1, V2)] {
  fn parse(str: String) -> ParsedValue[(V1, V2)] {
    let r1 = (self.parse)(str)
    match r1.0 {
      Ok((curr, rest)) => {
        let r2 = (lexer2.parse)(rest)
        match r2.0 {
          Err(err) => ParsedValue(Err(err))
          Ok((curr2, rest2)) => ParsedValue(Ok(((curr, curr2), rest2)))
        }
      }
      Err(err) => ParsedValue(Err(err))
    }
  }

  {
    parse,
  }

}

fn Lexer::or[V](self: Lexer[V], lexer2: Lexer[V]) -> Lexer[V] {
  fn parse(str: String) -> ParsedValue[V] {
    let r1 = (self.parse)(str)
    match r1.0 {
      Ok(_) => r1
      Err(_) => {
        let r2 = (lexer2.parse)(str)
        match r2.0 {
          Ok(_) => r2
          Err(_) => r2
        }
      }
    }
  }
  {
    parse,
  }
}

fn Lexer::map[V, V2](self: Lexer[V], f: (V) -> V2) -> Lexer[V2] {
  fn parse(str: String) -> ParsedValue[V2] {
    let r1 = (self.parse)(str)
    match r1 {
      ParsedValue(Ok((curr, rest))) => ParsedValue(Ok((f(curr), rest)))
      ParsedValue(Err(err)) => ParsedValue(Err(err))
    }
  }
  {
    parse,
  }
}

fn Lexer::many[V](self: Lexer[V]) -> Lexer[List[V]] {
  fn parse(str: String) -> ParsedValue[List[V]] {
    let mut result: List[V] = List::Nil
    let mut rest = str
    while true {
      if rest.length() == 0 {
        return ParsedValue(Ok((result, rest)))
      }
      match (self.parse)(rest) {
        ParsedValue(Ok((curr, rest_))) => {
          result = List::Cons(curr, result)
          rest = rest_
          continue
        }
        ParsedValue(Err(err)) => {
          return ParsedValue(Err(err))
        }
      }
    }
    // ParsedValue(Ok((result, rest)))
    abort("unimplemented")
  }
  {
    parse,
  }
}

fn init {
  
}

```

In the function Lexer::many, the while loop will break and return when the rest string is empty, while the type of while loop expression is Unit which cause compiler error of type mismatch.  
Expected behaviour: the type of while loop expression should not be Unit when it has return statement in the body.

 ![image](https://discuss.moonbitlang.com/uploads/default/original/1X/5a03789e33bb03b26ccf1282418799c24da5bc2a.png)

---

<div class="post-metadata">

**Author:** ![Yu-zh](https://discuss.moonbitlang.com/user_avatar/discuss.moonbitlang.com/yu-zh/32/90_2.png) [@Yu-zh](https://discuss.moonbitlang.com/u/Yu-zh)\
**Post date:** [February 20, 2024, 6:21am UTC](https://discuss.moonbitlang.com/t/return-in-while-loop-is-not-expected-behaviour/161/2 "2024-02-20T06:21:41Z")

</div>

Hi there! Currently the type of a while-loop is always Unit. There is no way to infer the type of a while-loop based on how `return` is used inside the while-loop. We will enhance the while-loop so that it can yield a value at the end in the near future. For your purpose, I would recommend you use the functional loop:

```auto
  fn parse(str: String) -> ParsedValue[List[V]] {
    loop str, List::Nil {
      "", acc => ParsedValue(Ok(acc, ""))
      rest, acc => {
        match (self.parse)(rest) {
          ParsedValue(Ok(curr, rest_)) => continue rest_, List::Cons(curr, acc)
          ParsedValue(Err(err)) => ParsedValue(Err(err))
        }
      }
    }
  }

```

You can find relevant document here: [MoonBit | MoonBit](https://www.moonbitlang.com/docs/syntax#functional-loop)
