lib/monad/identity/usage-rules.md

# `Funx.Monad.Identity` Usage Rules

## LLM Guidance

### Functional Programming Foundation

**CRITICAL Elixir Implementation**: All monadic operations are under `Funx.Monad` protocol

- **NO separate Functor/Applicative protocols** - Elixir protocols cannot be extended after definition
- Always use `Monad.map/2`, `Monad.bind/2`, `Monad.ap/2` or import `Funx.Monad`
- Different from Haskell's separate Functor, Applicative, Monad typeclasses

**Identity**: The simplest possible monad - a transparent wrapper

- `identity(value)` - wraps any value with no additional behavior
- **No side effects**: Unlike Maybe (absence) or Either (errors)
- **Transparent operations**: All operations work directly on the wrapped value
- **Foundation monad**: Used for learning, testing, and building other monads
- **Laws satisfied trivially**: All monad laws hold automatically

### When to Use Identity

**✅ Use Identity for:**

- **Testing monadic code**: Simplest monad for unit tests
- **Learning FP concepts**: Understand map/bind/ap without side effects
- **Polymorphic functions**: Code that works with any monad
- **Prototyping**: Placeholder before choosing real monad

**❌ Don't use Identity for:**

- **Production business logic**: Usually need Maybe/Either semantics
- **Error handling**: Identity has no failure concept
- **Optional values**: Identity wraps everything, no absence

### Context Clues

**User language → Identity patterns:**

- "simplest monad" → Identity is the canonical minimal monad
- "test my monad code" → Use Identity for predictable testing
- "works with any monad" → Write polymorphic code using Identity for examples
- "learning functional programming" → Start with Identity to understand concepts

## Quick Reference

- Use `identity(value)` to wrap any value transparently
- All operations work directly on the wrapped value with no special behavior
- `run_identity(wrapped_value)` to extract the value
- Import `Funx.Monad` for `map`, `bind`, `ap` operations
- Perfect for testing, learning, and polymorphic programming
- Satisfies all monad laws trivially due to its simplicity

## Overview

`Funx.Monad.Identity` is the simplest monad - a transparent wrapper with no additional behavior.

Use Identity for:
- Learning monadic operations without complexity
- Testing monadic code with predictable behavior
- Writing polymorphic functions that work with any monad
- Building and understanding more complex monads

**Key insight**: Identity is "just a wrapper" - it provides the monadic interface while doing absolutely nothing else. This makes it perfect for understanding what the interface itself provides.

## Constructor

### `identity/1` - Wrap Any Value

Creates an Identity monad containing a value:

```elixir
Identity.identity(42)              # Identity(42)
Identity.identity("hello")         # Identity("hello")
Identity.identity([1, 2, 3])       # Identity([1, 2, 3])
Identity.identity(%{key: :value})  # Identity(%{key: :value})
```

### `run_identity/1` - Extract the Value

Extracts the wrapped value from an Identity:

```elixir
Identity.identity(42) |> Identity.run_identity()     # 42
Identity.identity("hello") |> Identity.run_identity() # "hello"
```

## Core Operations

### `map/2` - Transform the Wrapped Value

Applies a function to the wrapped value:

```elixir
import Funx.Monad

Identity.identity(5)
|> map(fn x -> x * 2 end)    # Identity(10)

Identity.identity("hello")
|> map(&String.upcase/1)     # Identity("HELLO")

Identity.identity([1, 2, 3])
|> map(&Enum.sum/1)          # Identity(6)
```

**Identity map behavior:**

- Function is always applied (no short-circuiting like Maybe)
- Result is always wrapped in Identity
- No side effects or special cases

### `bind/2` - Chain Identity Operations

Chains operations that return Identity values:

```elixir
import Funx.Monad

# Functions that return Identity
double_wrapped = fn x -> Identity.identity(x * 2) end
stringify_wrapped = fn x -> Identity.identity(to_string(x)) end
upcase_wrapped = fn s -> Identity.identity(String.upcase(s)) end

Identity.identity(5)
|> bind(double_wrapped)        # Identity(10)
|> bind(stringify_wrapped)     # Identity("10")
|> bind(upcase_wrapped)        # Identity("10")
```

**Identity bind behavior:**

- Always applies the function (no conditional logic)
- Automatically flattens nested Identity values
- Perfect for demonstrating monadic composition

### `ap/2` - Apply Functions Across Identity Values

Applies a wrapped function to a wrapped value:

```elixir
import Funx.Monad

# Function wrapped in Identity
Identity.identity(fn x -> x + 10 end)
|> ap(Identity.identity(5))          # Identity(15)

# Multiple arguments with curried function
add = fn x -> fn y -> x + y end end

Identity.identity(add)
|> ap(Identity.identity(3))          # Identity(fn y -> 3 + y end)
|> ap(Identity.identity(4))          # Identity(7)

# String concatenation
concat = fn x -> fn y -> x <> y end end

Identity.identity(concat)
|> ap(Identity.identity("Hello, "))
|> ap(Identity.identity("World!"))   # Identity("Hello, World!")
```

**Identity ap behavior:**

- Always applies function to value (no failure cases)
- Demonstrates applicative functor pattern clearly
- Perfect for learning function application in context

## Testing with Identity

### Unit Testing Monad Laws

```elixir
defmodule IdentityLawsTest do
  use ExUnit.Case
  import Funx.Monad
  
  test "left identity law" do
    value = 42
    f = fn x -> Identity.identity(x * 2) end
    
    # Left identity: pure(x) |> bind(f) == f.(x)
    # Wrapping a value then binding should equal direct application
    left = bind(Identity.identity(value), f)
    right = f.(value)
    
    assert left == right
  end
  
  test "right identity law" do
    m = Identity.identity(42)
    
    # Right identity: m |> bind(pure) == m
    # Binding with pure should leave the monad unchanged
    result = bind(m, &Identity.identity/1)
    
    assert result == m
  end
  
  test "associativity law" do
    m = Identity.identity(42)
    f = fn x -> Identity.identity(x * 2) end
    g = fn x -> Identity.identity(x + 10) end
    
    # Associativity: (m |> bind(f)) |> bind(g) == m |> bind(fn x -> bind(f.(x), g) end)
    # Order of binding operations doesn't matter
    left = bind(bind(m, f), g)
    right = bind(m, fn x -> bind(f.(x), g) end)
    
    assert left == right
  end
  
  test "functor laws" do
    m = Identity.identity(42)
    f = fn x -> x * 2 end
    g = fn x -> x + 10 end
    
    # map(id, m) == m
    assert map(m, &Function.identity/1) == m
    
    # map(f . g, m) == map(f, map(g, m))
    composed = fn x -> f.(g.(x)) end
    assert map(m, composed) == map(map(m, g), f)
  end
end
```

### Testing Polymorphic Functions

```elixir
defmodule PolymorphicTest do
  use ExUnit.Case
  import Funx.Monad
  
  # A function that works with any monad
  def process_data(monad_value) do
    monad_value
    |> map(&to_string/1)
    |> bind(fn s -> 
      if String.length(s) > 3 do
        # Return appropriate monad type
        case monad_value do
          %Identity{} -> Identity.identity(String.upcase(s))
          %Maybe{} -> Maybe.just(String.upcase(s))
          %Either{} -> Either.right(String.upcase(s))
        end
      else
        case monad_value do
          %Identity{} -> Identity.identity("TOO SHORT")
          %Maybe{} -> Maybe.nothing()
          %Either{} -> Either.left("String too short")
        end
      end
    end)
  end
  
  test "polymorphic function with Identity" do
    # Test with long string
    result = process_data(Identity.identity(12345))
    assert result == Identity.identity("12345")
    
    # Test with short string  
    result = process_data(Identity.identity(42))
    assert result == Identity.identity("TOO SHORT")
  end
end
```

## Polymorphic Programming

Identity is perfect for learning and testing polymorphic monad code:

```elixir
# Generic function that works with any monad
def transform_and_chain(monad_value) do
  monad_value
  |> Monad.map(&(&1 + 5))              # Add 5
  |> Monad.bind(fn x -> 
    case monad_value do                  # Return appropriate type
      %Identity{} -> Identity.identity(x * 2)
      %Maybe{} -> Maybe.just(x * 2)
      %Either{} -> Either.right(x * 2)
    end
  end)
end

# Test with Identity - predictable, simple behavior
Identity.identity(10)
|> transform_and_chain()  # Identity(30)

# Same function works with other monads
Maybe.just(10)
|> transform_and_chain()  # Just(30)
```

### Custom Monad Implementation Example

```elixir
# Identity shows how to implement monads from scratch
defmodule CustomMonad do
  defstruct [:value]
  
  # Note: pure/1 is the convention used in Haskell/FP literature
  # It maps to identity/1 in this codebase
  def pure(value), do: %CustomMonad{value: value}
  
  defimpl Funx.Monad do
    def map(%CustomMonad{value: v}, f), do: CustomMonad.pure(f.(v))
    
    def bind(%CustomMonad{value: v}, f), do: f.(v)
    
    def ap(%CustomMonad{value: f}, %CustomMonad{value: v}) do
      CustomMonad.pure(f.(v))
    end
  end
end

# This custom monad behaves exactly like Identity
CustomMonad.pure(42)
|> Monad.map(&(&1 * 2))  # %CustomMonad{value: 84}
```

## Performance Characteristics

### Minimal Overhead

```elixir
# Identity has almost no runtime overhead
# It's essentially a tagged tuple with one element

defmodule PerformanceTest do
  def identity_operations(n) do
    # These operations are very fast
    1..n
    |> Enum.reduce(Identity.identity(0), fn i, acc ->
      acc
      |> Monad.map(&(&1 + i))
      |> Monad.bind(fn x -> Identity.identity(x * 2) end)
      |> Monad.map(&rem(&1, 1000))
    end)
  end
  
  def plain_operations(n) do
    # Compare with plain operations
    1..n
    |> Enum.reduce(0, fn i, acc ->
      (acc + i)
      |> (&(&1 * 2)).()
      |> rem(1000)
    end)
  end
end

# The Identity version will be only slightly slower than plain operations
# due to the minimal wrapping/unwrapping overhead
```

### Memory Usage

```elixir
# Identity uses minimal memory - just a wrapper struct
identity_value = Identity.identity("Hello, World!")

# Memory layout is approximately:
# %Identity{value: "Hello, World!"}
# Just the string plus a small struct wrapper

# Compare with other monads:
maybe_value = Maybe.just("Hello, World!")     # Similar overhead
either_value = Either.right("Hello, World!")  # Similar overhead
```

## String Representation

Identity implements String.Chars for easy IEx interaction:

```elixir
Identity.identity(42) |> to_string()     # "Identity(42)"
Identity.identity("hello") |> to_string() # "Identity(\"hello\")"
```

## Learning Patterns

### Understanding Monad Interface

```elixir
defmodule MonadTutorial do
  import Funx.Monad
  
  # Identity helps understand what each operation does
  def demonstrate_map() do
    # map transforms the value inside
    result = Identity.identity(5)
    |> map(fn x -> x * x end)
    
    IO.puts("map: Identity(5) -> Identity(25)")
    result  # Identity(25)
  end
  
  def demonstrate_bind() do
    # bind chains operations that return wrapped values
    double_it = fn x -> Identity.identity(x * 2) end
    
    result = Identity.identity(5)
    |> bind(double_it)
    
    IO.puts("bind: Identity(5) -> Identity(10)")  
    result  # Identity(10)
  end
  
  def demonstrate_ap() do
    # ap applies wrapped functions to wrapped values
    add_fn = fn x -> fn y -> x + y end end
    
    result = Identity.identity(add_fn)
    |> ap(Identity.identity(3))
    |> ap(Identity.identity(7))
    
    IO.puts("ap: Identity(add) + Identity(3) + Identity(7) -> Identity(10)")
    result  # Identity(10)
  end
  
  def show_difference_from_maybe() do
    # Same operations with Maybe show the difference
    transform = fn x -> x * 2 end
    
    # Identity always transforms
    identity_result = Identity.identity(5) |> map(transform)
    # Identity(10)
    
    # Maybe might not transform (if Nothing)
    maybe_result1 = Maybe.just(5) |> map(transform)      # Maybe.just(10) 
    maybe_result2 = Maybe.nothing() |> map(transform)    # Maybe.nothing()
    
    # Identity is predictable, Maybe depends on presence
  end
end
```

Identity helps you understand monadic patterns without complexity:

```elixir
# Pattern recognition: Transform -> Validate -> Chain
def learn_pattern(value) do
  Identity.identity(value)
  |> map(&(&1 + 10))           # Transform: add 10
  |> bind(fn x ->              # Validate and chain
    if x > 15 do
      Identity.identity("large: #{x}")
    else
      Identity.identity("small: #{x}")
    end
  end)
end

learn_pattern(10)  # Identity("large: 20")
learn_pattern(3)   # Identity("small: 13")
```

## Integration with Utils

```elixir
# Identity works seamlessly with Utils functions
add_ten = Funx.Utils.curry_r(&+/2).(10)

Identity.identity(5)
|> Monad.map(add_ten)        # Identity(15)

# Function composition in monadic context  
identity_pipeline = fn value ->
  Identity.identity(value)
  |> Monad.map(&(&1 + 1))    # Add 1
  |> Monad.map(&(&1 * 2))    # Multiply by 2  
  |> Monad.map(&(&1 - 3))    # Subtract 3
end

identity_pipeline.(5)        # Identity(9)
```

### Testing Other Monads

```elixir
defmodule MonadTester do
  import Funx.Monad
  
  # Test the same logic across different monads
  def test_computation(monad_constructor, value) do
    computation = fn m ->
      m
      |> map(&(&1 * 2))
      |> bind(fn x ->
        monad_constructor.(x + 5)
      end)
      |> map(&to_string/1)
    end
    
    monad_constructor.(value)
    |> computation.()
  end
  
  def run_tests() do
    # Test with Identity - always succeeds predictably
    identity_result = test_computation(&Identity.identity/1, 10)
    # Identity("25")
    
    # Test with Maybe - succeeds with just
    maybe_result = test_computation(&Maybe.just/1, 10) 
    # Maybe.just("25")
    
    # Test with Either - succeeds with right
    either_result = test_computation(&Either.right/1, 10)
    # Either.right("25")
    
    # Identity gives us the baseline expected behavior
    %{
      identity: identity_result,
      maybe: maybe_result, 
      either: either_result
    }
  end
end
```

## Advanced Patterns

### Custom Monad Implementation Guide

```elixir
# Identity shows the minimal implementation needed for a monad

defmodule CustomMonad do
  defstruct [:value]
  
  # Constructor (like Identity.identity/1)
  def pure(value), do: %__MODULE__{value: value}
  
  # Functor implementation (like map)
  def fmap(%__MODULE__{value: v}, f) do
    %__MODULE__{value: f.(v)}
  end
  
  # Monad implementation (like bind)
  def bind(%__MODULE__{value: v}, f) do
    f.(v)  # f should return another CustomMonad
  end
  
  # Extractor (like run_identity)
  def extract(%__MODULE__{value: v}), do: v
end

# This follows the same pattern as Identity but could add behavior
# For example, logging, counting operations, etc.

defimpl Funx.Monad, for: CustomMonad do
  def map(monad, f), do: CustomMonad.fmap(monad, f)
  def bind(monad, f), do: CustomMonad.bind(monad, f)
  def ap(monad_f, monad_x) do
    # Standard applicative implementation
    CustomMonad.bind(monad_f, fn f ->
      CustomMonad.fmap(monad_x, f)
    end)
  end
end
```

### Monad Stack Exploration

```elixir
# Identity at the bottom of monad transformer stacks

# MaybeT Identity a ≅ Maybe a
# EitherT e Identity a ≅ Either e a  
# StateT s Identity a ≅ State s a

# Identity is often the "base" monad in transformer stacks
# Understanding Identity helps understand how transformers work

defmodule StackExample do
  # Simulate MaybeT Identity (which is just Maybe)
  def maybe_t_identity_example(value) do
    # This is conceptually MaybeT Identity, but it's just Maybe
    case value do
      nil -> Maybe.nothing()
      x when x > 0 -> Maybe.just(x * 2)
      _ -> Maybe.nothing()
    end
  end
  
  # If we had a real MaybeT Identity, it would look like:
  # newtype MaybeT Identity a = Identity (Maybe a)
  # But since Identity is transparent, it's just Maybe a
end
```

## Common Patterns and Use Cases

### Educational Sequencing

```elixir
# Use Identity to learn sequence/traverse patterns
defmodule SequenceExample do
  import Funx.Monad
  
  def sequence_identities(list_of_identities) do
    # This is educational - sequence([Identity a]) -> Identity [a]
    values = list_of_identities |> Enum.map(&Identity.run_identity/1)
    Identity.identity(values)
  end
  
  def traverse_with_identity(list, f) do
    # Apply f to each element, collect in Identity
    results = list |> Enum.map(f) |> Enum.map(&Identity.run_identity/1)
    Identity.identity(results)
  end
  
  # Examples
  def examples() do
    identities = [Identity.identity(1), Identity.identity(2), Identity.identity(3)]
    sequenced = sequence_identities(identities)
    # Identity([1, 2, 3])
    
    numbers = [1, 2, 3]
    traversed = traverse_with_identity(numbers, fn x -> Identity.identity(x * 2) end)
    # Identity([2, 4, 6])
  end
end
```

### Debugging Monad Chains

```elixir
# Identity for debugging complex monad chains
defmodule DebugMonad do
  import Funx.Monad
  
  def debug_chain(value) do
    # Use Identity to debug logic without side effects
    Identity.identity(value)
    |> map(fn x -> 
      IO.puts("Step 1: #{x}")
      x * 2
    end)
    |> bind(fn x ->
      IO.puts("Step 2: #{x}")
      Identity.identity(x + 10)
    end)
    |> map(fn x ->
      IO.puts("Step 3: #{x}")
      to_string(x)
    end)
  end
  
  # Once logic is correct, switch to real monad
  def production_chain(value) do
    Maybe.just(value)  # or Either.right(value)
    |> map(fn x -> x * 2 end)
    |> bind(fn x -> 
      if x > 0 do
        Maybe.just(x + 10)
      else
        Maybe.nothing()
      end
    end)
    |> map(&to_string/1)
  end
end
```

## Summary

Identity provides the foundation for understanding monadic programming:

**Core Operations:**

- `identity/1`: Wrap any value transparently
- `run_identity/1`: Extract the wrapped value
- `map/2`: Transform wrapped values with no side effects
- `bind/2`: Chain Identity-returning operations with automatic flattening
- `ap/2`: Apply wrapped functions to wrapped values

**Key Uses:**

- **Learning**: Understand monad interface without complexity
- **Testing**: Predictable behavior for unit tests
- **Polymorphism**: Write generic code that works with any monad
- **Prototyping**: Placeholder before choosing real monad
- **Debugging**: Validate monad chain logic

**Mathematical Properties:**

- **Functor**: `map` applies function directly to wrapped value
- **Applicative**: `ap` applies function with no failure cases
- **Monad**: `bind` chains operations with trivial flattening
- **Laws**: All monad laws satisfied automatically due to simplicity

Remember: Identity is "just a wrapper" - it provides the monadic interface while being completely transparent. This makes it perfect for learning what monads are and testing monadic code without the complexity of real-world side effects.