User:Kevin Reid/Defining algebraic data types

From Erights

Jump to: navigation, search

Quite incomplete, but better here than on my hard disk. Top is the partial implementation, bottom is some possible actual usage interfaces:

def ne(s) { return makeNounExpr(s, null, s) }
def algebraic(constructors :List[String]) {
  def constrSet := constructors.asSet()
  return def aGenMap {
    to fetch(`make$upperName`, _) {
      def lowerName := upperName(0,1).toLowerCase() + upperName(1)
      require(lowerName != upperName)
      def upperNoun := ne(upperName)
      def prog := e`
        interface $upperNoun guards ${ne(`${upperName}Stamp`)} {}
        return def ${ne(`make$upperName`)} {
          to asType() { return $upperNoun }
          match [constr ? constrSet.contains(constr), args] {
            return def ad implements AdStamp {
              ...
            }
          }
          match [`match__@constr/@n` ? constrSet.contains(constr), [specimen, ejector]] {
            ...
          }
        }
      `
      return prog.eval(safeScope)
    }
    to without(n) {
      # underconstrained
      return [].asMap()
    }
  }
}



# Haskell: "data Either a b = Left a | Right b"

def [=> makeEither] := algebraic(["left", "right"])
def [=> makeEither] := algebraic`a b -> left(a) | right(b)`
Personal tools
more tools