Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Yep, the multiple same type issue definitely happens and that compicates client side matching. In my experience it has been infrequent enough that having to make the a couple wrapper classes would be preferable. Sometime tuples can be very ambiguous, take points for example. Point(x:Int,y:Int) is similar to (Int,Int), however sometimes the anonymity is nice so you will want to have both options.

The Boilerplate grows really fast as you try to pass results up a call hierachy.

So let me extend the example to demonstrate it how it doesn't scale:

  //Sorry for the Scala-ness
  //Presume a mapByType partial function on all discriminated unions if the union value is of that type, then it calls
  //the partial function otherwise it just returns whatever it's current value is
  def lexAndParse : ParseError | LexError | Int | String = lex().mapByType{ case t : Token => parse(t) }
  newtype LexError = Err
  def lex() : LexError | Token = ...

  newtype ParseError = Err
  def parse(t : Token) :  ParseError | Int | String = {
      tryParseInt(t).orElse(tryParseString(t)).getOrElse(ParseError("$t not Int Or String"))) }
    }
  def tryParseInt(token : Token) : Option[Int] = ...
  def tryParseString(token : Token) : Option[String] = ...

versus:

  pub enum LexParseResult {
    LexError(Err) 
    ParseError(Err) 
    IntResult(Int)
    StringResult(String)
  }
  def lexAndParse : LexAndParseResult = {
    match lex() {
      LexResult.LexError(e) => LexAndParseResult.LexError(e)
      LexResult.TokenResult(t) => match parse(t) {
         ParseResult.ParseError(e) => LexParseResult.ParseError(e)
         ParseResult.IntResult(e) => LexParseResult.IntResult(e)
         ParseResult.StringResult(e) => LexParseResult.StringResult(e)
      }
    }
  }

  pub enum LexResult {
    LexError(Err) 
    TokenResult(Token)
  }
  def lex : LexResult

  pub enum ParseResult {
    ParseError(Err) 
    IntResult(Int)
    StringResult(String)
  }
  def parse(token : Token) : ParseResult = {
     match lex(){
       Token(t) => 
        tryParseInt(t).map(r=>ParseResult.IntResult(r)).orElse(tryParseString.map(r=>ParseResult.StringResult(r) )).getOrElse(ParseResult.ParseError("$t not Int Or String"))) }
       LexError(e) =>  ParseResult.LexError(e)
    }
  }
  def tryParseInt(token : Token) : Option[Int] = ...
  def tryParseString(token : Token) : Option[String] = ...


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: