Skip to content

Instantly share code, notes, and snippets.

@yitsushi
Last active February 9, 2022 11:16
Show Gist options
  • Save yitsushi/440ddbe42be6fb6bfcdc9e5e6d9c2384 to your computer and use it in GitHub Desktop.
Save yitsushi/440ddbe42be6fb6bfcdc9e5e6d9c2384 to your computer and use it in GitHub Desktop.
Go: Maybe with foldl
package main
import (
"fmt"
"constraints"
)
func FoldlIter[T any, R any](init R, list (<- chan T), fold func(carry R, next T) R) R {
for value := range list {
init = fold(init, value)
}
return init
}
func Foldl[T any, R any](init R, list []T, fold func(carry R, next T) R) R {
for _, value := range list {
init = fold(init, value)
}
return init
}
type Maybe[T any] struct {
value T
isNothing bool
}
func (m Maybe[T]) Value() T {
return m.value
}
func (m Maybe[T]) IsNothing() bool {
return m.isNothing
}
func Nothing[T any]() Maybe[T] {
return Maybe[T]{isNothing: true}
}
func Just[T any](value T) Maybe[T] {
return Maybe[T]{value: value}
}
func readFromUser() (chan Maybe[int]) {
ch := make (chan Maybe[int])
myList := []Maybe[int]{
Just(12),
Just(2),
Nothing[int](),
Just(8),
}
go func () {
for _, v := range myList {
ch <- v
}
close(ch)
}()
return ch
}
func readFromUserStr() (chan Maybe[string]) {
ch := make (chan Maybe[string])
myList := []Maybe[string]{
Just("123"),
Just("asd"),
Nothing[string](),
Just(",./"),
}
go func () {
for _, v := range myList {
ch <- v
}
close(ch)
}()
return ch
}
// ignore the constraints.Ordered part, i'm just lazy to define a set that can handle the "add" operation.
func add[T constraints.Ordered](c Maybe[T], value Maybe[T]) Maybe[T] {
if c.IsNothing() {
return value
}
if value.IsNothing() {
return c
}
return Just(c.Value() + value.Value())
}
func main() {
result := FoldlIter(
Just(0),
readFromUser(),
add[int],
)
resultStr := FoldlIter(
Just(""),
readFromUserStr(),
add[string],
)
fmt.Println(result)
fmt.Println(resultStr)
}
{22 false}
{123asd,./ false}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment