Structs in Idris

Our first program demonstrates how to define and use structs. Structs are useful for grouping data together to form records.

This person struct type has name and age fields.

record Person where
  constructor MkPerson
  name : String
  age : Int

-- `newPerson` constructs a new person record with the given name.
newPerson : String -> Person
newPerson name = MkPerson name 42

main : IO ()
main = do
  -- This syntax creates a new record.
  putStrLn $ show $ MkPerson "Bob" 20

-- You can name the fields when initializing a record.
  putStrLn $ show $ MkPerson { name = "Alice", age = 30 }

-- Omitted fields will be zero-valued (or default).
  putStrLn $ show $ MkPerson { name = "Fred" }

-- An `&` prefix yields a pointer to the record.
  let ann = MkPerson { name = "Ann", age = 40 }
  putStrLn $ show ann

-- It’s idiomatic to encapsulate new record creation in constructor functions.
  putStrLn $ show $ newPerson "Jon"

-- Access record fields with a dot.
  let sean = MkPerson { name = "Sean", age = 50 }
  putStrLn $ show $ sean.name

-- You can also use dots with record pointers - the pointers are automatically dereferenced.
  let sp = sean
  putStrLn $ show $ sp.age

-- Records are mutable.
  let spMutable = sp
  let spMutableUpdated = spMutable { age = 51 }
  putStrLn $ show $ spMutableUpdated.age

-- If a record type is only used for a single value, we don’t have to give it a name.
-- The value can have an anonymous record type.
  let dog = MkPerson "Rex" 1
  putStrLn $ show $ dog

To run the program, save the code into a file with an .idr extension, for example, structs.idr, and use the Idris compiler and interpreter.

$ idris structs.idr -o structs
$ ./structs
MkPerson "Bob" 20
MkPerson "Alice" 30
MkPerson "Fred" 0
MkPerson "Ann" 40
MkPerson "Jon" 42
"Sean"
50
51
MkPerson "Rex" 1

Now that we can run and build basic Idris programs, let’s learn more about the language.