Skip to main content
Version: v2.2.82 (latest)
Reference · Core Type

IOOption

Combine lazy evaluation (IO) with optional values (Option). IOOption[A] represents a synchronous computation with side effects that may produce no value.

01

Overview

type_definition.go
package iooption

// IOOption is IO of Option
type IOOption[A any] = IO[Option[A]]
// Which expands to: func() Option[A]

When to Use

Use IOOption WhenUse IOResult When
Optional results (cache miss, search)Operations that can fail with errors
No error information neededNeed error messages
Absence is not an errorFailure needs explanation
02

Core API

Constructors

FunctionSignatureDescription
Somefunc Some[A any](value A) IOOption[A]Create IOOption with value
Nonefunc None[A any]() IOOption[A]Create empty IOOption
Offunc Of[A any](value A) IOOption[A]Alias for Some
FromIOfunc FromIO[A any](io IO[A]) IOOption[A]Lift IO to IOOption
FromOptionfunc FromOption[A any](opt Option[A]) IOOption[A]Lift Option to IOOption
FromNillablefunc FromNillable[A any](io IO[*A]) IOOption[A]From IO of pointer

Transformations

FunctionSignatureDescription
Mapfunc Map[A, B any](f func(A) B) func(IOOption[A]) IOOption[B]Transform value if present
Chainfunc Chain[A, B any](f func(A) IOOption[B]) func(IOOption[A]) IOOption[B]Sequence operations
Filterfunc Filter[A any](pred func(A) bool) func(IOOption[A]) IOOption[A]Keep only if predicate holds

Combining

FunctionSignatureDescription
Altfunc Alt[A any](second IOOption[A]) func(IOOption[A]) IOOption[A]Fallback on None
GetOrElsefunc GetOrElse[A any](f func() IO[A]) func(IOOption[A]) IO[A]Extract with default
03

Usage Examples

Basic Operations

basic.go
package main

import (
  IOO "github.com/IBM/fp-go/v2/iooption"
)

func main() {
  // Create IOOption values
  some := IOO.Some(42)
  none := IOO.None[int]()
  
  // Execute
  result := some()  // Option[int] = Some(42)
  result = none()   // Option[int] = None
}

Cache Lookup

cache.go
package main

import (
  IOO "github.com/IBM/fp-go/v2/iooption"
)

func getFromCache(key string) IOO.IOOption[Data] {
  return func() option.Option[Data] {
      if val, ok := cache.Get(key); ok {
          return option.Some(val.(Data))
      }
      return option.None[Data]()
  }
}

func getWithFallback(key string) IO.IO[Data] {
  return IOO.GetOrElse(func() IO.IO[Data] {
      return fetchFromDB(key)
  })(getFromCache(key))
}

func main() {
  data := getWithFallback("user:123")()
}

Search Operations

search.go
package main

import (
  IOO "github.com/IBM/fp-go/v2/iooption"
  F "github.com/IBM/fp-go/v2/function"
)

func findUser(email string) IOO.IOOption[User] {
  return func() option.Option[User] {
      users := db.QueryUsers("email = ?", email)
      if len(users) > 0 {
          return option.Some(users[0])
      }
      return option.None[User]()
  }
}

func findActiveUser(email string) IOO.IOOption[User] {
  return F.Pipe1(
      findUser(email),
      IOO.Filter(func(u User) bool {
          return u.Active
      }),
  )
}

func main() {
  result := findActiveUser("alice@example.com")()
  // Option[User]
}

Chaining Optional Operations

chaining.go
package main

import (
  IOO "github.com/IBM/fp-go/v2/iooption"
  F "github.com/IBM/fp-go/v2/function"
)

func getUserProfile(id string) IOO.IOOption[Profile] {
  return F.Pipe2(
      findUser(id),
      IOO.Chain(func(u User) IOO.IOOption[Profile] {
          return loadProfile(u.ProfileID)
      }),
      IOO.Filter(func(p Profile) bool {
          return p.Visible
      }),
  )
}
04

Common Patterns

Pattern 1: Fallback Chain

fallback.go
package main

import (
  IOO "github.com/IBM/fp-go/v2/iooption"
  F "github.com/IBM/fp-go/v2/function"
)

func getData(key string) IOO.IOOption[Data] {
  return F.Pipe2(
      getFromMemCache(key),
      IOO.Alt(getFromRedis(key)),
      IOO.Alt(getFromDatabase(key)),
  )
}

Pattern 2: Optional Configuration

config.go
package main

import (
  IOO "github.com/IBM/fp-go/v2/iooption"
)

func loadOptionalConfig(path string) IOO.IOOption[Config] {
  return func() option.Option[Config] {
      data, err := os.ReadFile(path)
      if err != nil {
          return option.None[Config]()
      }
      
      var cfg Config
      if err := json.Unmarshal(data, &cfg); err != nil {
          return option.None[Config]()
      }
      
      return option.Some(cfg)
  }
}

func getConfig() IO.IO[Config] {
  return IOO.GetOrElse(func() IO.IO[Config] {
      return IO.Of(defaultConfig())
  })(loadOptionalConfig("config.json"))
}