How do I use a constrained type as a field in a record?

← Advanced Type System · Ref: Q1074

Constrained types work as record fields, but the constructor parameter must match the constrained type, not the base type.

Define the constrained type:

  defines type
    Percentage as Integer constrain as
      >= 0 and <= 100

Use it in a record:

  defines record
    ExamResult
      studentName as String: String()
      score as Percentage: Percentage(0)
      ExamResult()
        -> studentName as String, score as Percentage
        this.studentName :=: studentName
        this.score :=: score
      default operator

IMPORTANT: The constructor parameter must be 'score as Percentage', not 'score as Integer'. Even though Percentage is based on Integer, they are distinct types.

In the program, create with the constrained type:

  result <- ExamResult("Alice", Percentage(85))

Not:

  result <- ExamResult("Alice", 85)    WRONG — 85 is Integer, not Percentage

See Q257 for constrained type basics. See Q717 for constrained type comparisons. See Q720 for constrainable types.

Example

defines module qa.advancedtypes.constrainedinrecord

  defines type

    Percentage as Integer constrain as
      >= 0 and <= 100

  defines record

    ExamResult
      studentName as String: String()
      score as Percentage: Percentage(0)

      ExamResult()
        ->
          studentName as String
          score as Percentage
        this.studentName :=: studentName
        this.score :=: score

      default operator

  defines program

    ConstrainedRecordDemo()
      stdout <- Stdout()

      result <- ExamResult("Alice", Percentage(85))
      stdout.println(`${result}`)

Common mistakes

E50060 — 85 is an Integer, not a Percentage. Use Percentage(85) to create the constrained type value explicitly.

Incorrect:

      result <- ExamResult("Alice", 85)

Correct:

      result <- ExamResult("Alice", Percentage(85))
Other ways to ask this
  • Can I put a constrained type in a record constructor?
  • Why does my constrained type field get a method resolution error?
  • How do I create a record with a Percentage field?

Coming from another language?

Java: no direct equivalent. Rust: newtype pattern. Python: no constraint at type level. EK9: constrained types are distinct types — constructor must use the constrained type.

Keywords: integer, record, field, percentage, type, constrained