Skip to content

Instantly share code, notes, and snippets.

@yordanoweb
Last active January 13, 2025 19:48
Show Gist options
  • Save yordanoweb/d6cafcee45db9392a2d08f7f4ffda70b to your computer and use it in GitHub Desktop.
Save yordanoweb/d6cafcee45db9392a2d08f7f4ffda70b to your computer and use it in GitHub Desktop.
Identity monad implemented in Go

Identity Monad in Go

package main

import (
	"fmt"
	"reflect"
)

// Identity represents the Identity monad.
type Identity struct {
	value interface{}
}

// Of creates a new Identity instance.
func Of(x interface{}) *Identity {
	return &Identity{x}
}

// Ap applies a function wrapped in another Identity to the current Identity.
func (i *Identity) Ap(f *Identity) *Identity {
	fn, ok := i.value.(func(interface{}) interface{})
	if !ok {
		// Handle the case where i.value is not a function
		return Of(nil) // or return an error Identity, depending on your needs
	}
	return f.Map(fn)
}

// Chain applies a function that returns an Identity and flattens the result.
func (i *Identity) Chain(fn func(interface{}) interface{}) interface{} {
	return i.Map(fn).Join()
}

// Inspect returns a string representation of the Identity.
func (i *Identity) Inspect() string {
	return fmt.Sprintf("Identity(%v)", i.value)
}

// GetType returns the type of the value inside the Identity.
func (i *Identity) GetType() string {
	return fmt.Sprintf("(Identity %v)", reflect.TypeOf(i.value))
}

// Join flattens the Identity structure.
func (i *Identity) Join() interface{} {
	return i.value
}

// Map applies a function to the value inside the Identity.
func (i *Identity) Map(fn func(interface{}) interface{}) *Identity {
	return Of(fn(i.value))
}

func main() {
	id := Of(42)
	fmt.Println(id.Inspect()) // Output: Identity(42)

	id2 := id.Map(func(x interface{}) interface{} {
		return x.(int) * 2
	})
	fmt.Println(id2.Inspect()) // Output: Identity(84)

	id3 := id2.Chain(func(x interface{}) interface{} {
		return Of(x.(int) + 10)
	})
	fmt.Println(id3.(*Identity).Inspect()) // Output: Identity(94)

	/////////////////////////////////////////////
	// Example for Ap method
	/////////////////////////////////////////////

	// Monad with func as its value
	fnId := Of(func(x interface{}) interface{} {
		return x.(int) + 5
	})
	result := fnId.Ap(id)
	fmt.Println(result.Inspect()) // Output: Identity(47)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment