Object Construction

Object Construction #

Although the primary purpose of go-optics is immutable updates to nested data structures it also provides powerful object graph query abilities. These are used to focus in the correct elements to update but equally these focused elements can be returned directly using the Get family of actions. However Get can return only a single value. In order to return multiple values they need to be collected together into a container.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
	data := []int{10, 20, 30, 40, 50}

	optic := Filtered(
		TraverseSlice[int](),
		Gte(30),
	)

	result := MustGet(
		SliceOf(
			optic,
			5, //Initial slice capacity
		),
		data,
	)

	fmt.Println(result)

This example focuses the values in the slice with a value >= 30 SliceOf collects those values into a new slice.

The values focused by an Optic also maintain their index this enables maps to also be constructed.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
	data := []string{"alpha", "beta", "gamma"}

	result, err := Get(
		MapOf(
			TraverseSlice[string](),
			5, //Initial slice capacity
		),
		data,
	)

	fmt.Println(result, err)

The index value of a traversed slice is the original slice index.This example produces the following map.

1
2
3
4
5
		map[int]string{
			0: "alpha",
			1: "beta",
			2: "gamma",
		},

Object construction in go-optics also supports modification. In this case the updated values in the updated collection are used to repopulate the original data structure. This is done by position. The index values are ignored during updates.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
	data := [][]string{
		[]string{"alpha", "beta"},
		[]string{"gamma", "delta"},
	}

	optic := SliceOf(
		Compose(
			TraverseSlice[[]string](),
			TraverseSlice[string](),
		),
		4, //Initial slice capacity
	)

	var result [][]string = MustModify(optic,
		Op(func(s []string) []string {

			fmt.Println(s)
			// []string{"alpha","beta","gamma","delta"}

			s[2] = "EDIT"
			return s
		}),
		data,
	)

	fmt.Println(result)

The slice passed to the modification Op is flattened values from the nested slices.

[]string{"alpha", "beta", "gamma", "delta"}

The modification Op changes the element at index 2.

The values in the return from the op are woven into the original structure. In this case the result is

1
2
3
4
		[][]string{
			{"alpha", "beta"},
			{"EDIT", "delta"},
		},

The element at index 2 was “gamma” and that is the value that now contains the updated value. This demonstrates the power of Optics to update complex nested structures with ease.

If the modified collection contains fewer values then the original values are used for the missing values. If the modified collection contains additional elements these elements are ignored.

The following object construction optics are available.

  • MapOf
  • ListOf
  • SliceOf
  • StringOf
  • T2Of
  • ColOf
  • SeqOf

Polymorphic versions are available with the suffix P. However the polymorphic versions will return an error if the modified collection has fewer elements than the original.