1
0
mirror of https://github.com/IBM/fp-go.git synced 2025-08-10 22:31:32 +02:00

doc: update presentation

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>
This commit is contained in:
Dr. Carsten Leue
2023-10-05 15:50:25 +02:00
parent 58c60c19e4
commit 541ebdb737
7 changed files with 294 additions and 9 deletions

View File

@@ -22,30 +22,28 @@ import (
)
type Const[E, A any] struct {
Value E
value E
}
func Make[E, A any](e E) Const[E, A] {
return Const[E, A]{Value: e}
return Const[E, A]{value: e}
}
func Unwrap[E, A any](c Const[E, A]) E {
return c.Value
return c.value
}
func Of[E, A any](m M.Monoid[E]) func(A) Const[E, A] {
return func(a A) Const[E, A] {
return Make[E, A](m.Empty())
}
return F.Constant1[A](Make[E, A](m.Empty()))
}
func MonadMap[E, A, B any](fa Const[E, A], f func(A) B) Const[E, B] {
return Make[E, B](fa.Value)
return Make[E, B](fa.value)
}
func MonadAp[E, A, B any](s S.Semigroup[E]) func(fab Const[E, func(A) B], fa Const[E, A]) Const[E, B] {
return func(fab Const[E, func(A) B], fa Const[E, A]) Const[E, B] {
return Make[E, B](s.Concat(fab.Value, fa.Value))
return Make[E, B](s.Concat(fab.value, fa.value))
}
}

View File

@@ -125,10 +125,29 @@ func MonadAp[B, E, A any](mab IOEither[E, func(A) B], ma IOEither[E, A]) IOEithe
return G.MonadAp[IOEither[E, B]](mab, ma)
}
// Ap is an alias of [ApPar]
func Ap[B, E, A any](ma IOEither[E, A]) func(IOEither[E, func(A) B]) IOEither[E, B] {
return G.Ap[IOEither[E, B], IOEither[E, func(A) B]](ma)
}
func MonadApPar[B, E, A any](mab IOEither[E, func(A) B], ma IOEither[E, A]) IOEither[E, B] {
return G.MonadApPar[IOEither[E, B]](mab, ma)
}
// ApPar applies function and value in parallel
func ApPar[B, E, A any](ma IOEither[E, A]) func(IOEither[E, func(A) B]) IOEither[E, B] {
return G.ApPar[IOEither[E, B], IOEither[E, func(A) B]](ma)
}
func MonadApSeq[B, E, A any](mab IOEither[E, func(A) B], ma IOEither[E, A]) IOEither[E, B] {
return G.MonadApSeq[IOEither[E, B]](mab, ma)
}
// ApSeq applies function and value sequentially
func ApSeq[B, E, A any](ma IOEither[E, A]) func(IOEither[E, func(A) B]) IOEither[E, B] {
return G.ApSeq[IOEither[E, B], IOEither[E, func(A) B]](ma)
}
func Flatten[E, A any](mma IOEither[E, IOEither[E, A]]) IOEither[E, A] {
return G.Flatten(mma)
}

View File

@@ -22,7 +22,7 @@ import (
G "github.com/IBM/fp-go/optics/traversal/generic"
)
// FromArray returns a traversal from an array for the identity monad
// FromArray returns a traversal from an array for the identity [Monoid]
func FromArray[E, A any](m M.Monoid[E]) G.Traversal[[]A, A, C.Const[E, []A], C.Const[E, A]] {
return AR.FromArray[[]A, E, A](m)
}

View File

@@ -6,6 +6,15 @@
],
"rangeStrategy": "bump",
"packageRules": [
{
"matchManagers": [
"gomod"
],
"matchDepTypes": [
"golang"
],
"enabled": false
},
{
"matchUpdateTypes": [
"major",

View File

@@ -0,0 +1,103 @@
// Copyright (c) 2023 IBM Corp.
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package examples
import (
"fmt"
"strconv"
E "github.com/IBM/fp-go/either"
F "github.com/IBM/fp-go/function"
S "github.com/IBM/fp-go/string"
)
func validatePort(port int) (int, error) {
if port > 0 {
return port, nil
}
return 0, fmt.Errorf("Value %d is not a valid port number", port)
}
func Example_either_monad() {
// func(string) E.Either[error, int]
atoi := E.Eitherize1(strconv.Atoi)
// func(int) E.Either[error, int]
valPort := E.Eitherize1(validatePort)
// func(string) E.Either[error, string]
makeUrl := F.Flow3(
atoi,
E.Chain(valPort),
E.Map[error](S.Format[int]("http://localhost:%d")),
)
fmt.Println(makeUrl("8080"))
// Output:
// Right[<nil>, string](http://localhost:8080)
}
func Example_either_idiomatic() {
makeUrl := func(port string) (string, error) {
parsed, err := strconv.Atoi(port)
if err != nil {
return "", err
}
valid, err := validatePort(parsed)
if err != nil {
return "", err
}
return fmt.Sprintf("http://localhost:%d", valid), nil
}
url, err := makeUrl("8080")
if err != nil {
panic(err)
}
fmt.Println(url)
// Output:
// http://localhost:8080
}
func Example_either_worlds() {
// func(string) E.Either[error, int]
atoi := E.Eitherize1(strconv.Atoi)
// func(int) E.Either[error, int]
valPort := E.Eitherize1(validatePort)
// func(string) E.Either[error, string]
makeUrl := F.Flow3(
atoi,
E.Chain(valPort),
E.Map[error](S.Format[int]("http://localhost:%d")),
)
// func(string) (string, error)
makeUrlGo := E.Uneitherize1(makeUrl)
url, err := makeUrlGo("8080")
if err != nil {
panic(err)
}
fmt.Println(url)
// Output:
// http://localhost:8080
}

View File

@@ -0,0 +1,156 @@
// Copyright (c) 2023 IBM Corp.
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package examples
import (
"fmt"
"strings"
F "github.com/IBM/fp-go/function"
N "github.com/IBM/fp-go/number"
L "github.com/IBM/fp-go/optics/lens"
)
type Person struct {
name string
age int
}
func (p Person) GetName() string {
return p.name
}
func (p Person) GetAge() int {
return p.age
}
func (p Person) SetName(name string) Person {
p.name = name
return p
}
func (p Person) SetAge(age int) Person {
p.age = age
return p
}
type Address struct {
city string
}
func (a Address) GetCity() string {
return a.city
}
func (a Address) SetCity(city string) Address {
a.city = city
return a
}
type Client struct {
person Person
address Address
}
func (c Client) GetPerson() Person {
return c.person
}
func (c Client) SetPerson(person Person) Client {
c.person = person
return c
}
func (c Client) GetAddress() Address {
return c.address
}
func (c Client) SetAddress(address Address) Client {
c.address = address
return c
}
func MakePerson(name string, age int) Person {
return Person{name, age}
}
func MakeClient(city string, name string, age int) Client {
return Client{person: Person{name, age}, address: Address{city}}
}
func Example_immutability_struct() {
p1 := MakePerson("Carsten", 53)
// func(int) func(Person) Person
setAge := F.Curry2(F.Swap(Person.SetAge))
p2 := F.Pipe1(
p1,
setAge(54),
)
fmt.Println(p1)
fmt.Println(p2)
// Output:
// {Carsten 53}
// {Carsten 54}
}
func Example_immutability_optics() {
// Lens[Person, int]
ageLens := L.MakeLens(Person.GetAge, Person.SetAge)
// func(Person) Person
incAge := L.Modify[Person](N.Inc[int])(ageLens)
p1 := MakePerson("Carsten", 53)
p2 := incAge(p1)
fmt.Println(p1)
fmt.Println(p2)
// Output:
// {Carsten 53}
// {Carsten 54}
}
func Example_immutability_lenses() {
// Lens[Person, string]
nameLens := L.MakeLens(Person.GetName, Person.SetName)
// Lens[Client, Person]
personLens := L.MakeLens(Client.GetPerson, Client.SetPerson)
// Lens[Client, string]
clientNameLens := F.Pipe1(
personLens,
L.Compose[Client](nameLens),
)
// func(Client) Client
upperName := L.Modify[Client](strings.ToUpper)(clientNameLens)
c1 := MakeClient("Böblingen", "Carsten", 53)
c2 := upperName(c1)
fmt.Println(c1)
fmt.Println(c2)
// Output:
// {{Carsten 53} {Böblingen}}
// {{CARSTEN 53} {Böblingen}}
}