mirror of
https://github.com/IBM/fp-go.git
synced 2025-08-10 22:31:32 +02:00
fix: add more examples
Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>
This commit is contained in:
10
ord/ord.go
10
ord/ord.go
@@ -131,7 +131,7 @@ func FromStrictCompare[A C.Ordered]() Ord[A] {
|
|||||||
return MakeOrd(strictCompare[A], strictEq[A])
|
return MakeOrd(strictCompare[A], strictEq[A])
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lt tests whether one value is _strictly less than_ another
|
// Lt tests whether one value is strictly less than another
|
||||||
func Lt[A any](O Ord[A]) func(A) func(A) bool {
|
func Lt[A any](O Ord[A]) func(A) func(A) bool {
|
||||||
return func(second A) func(A) bool {
|
return func(second A) func(A) bool {
|
||||||
return func(first A) bool {
|
return func(first A) bool {
|
||||||
@@ -140,7 +140,7 @@ func Lt[A any](O Ord[A]) func(A) func(A) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Leq Tests whether one value is less or equal than_ another
|
// Leq Tests whether one value is less or equal than another
|
||||||
func Leq[A any](O Ord[A]) func(A) func(A) bool {
|
func Leq[A any](O Ord[A]) func(A) func(A) bool {
|
||||||
return func(second A) func(A) bool {
|
return func(second A) func(A) bool {
|
||||||
return func(first A) bool {
|
return func(first A) bool {
|
||||||
@@ -150,9 +150,9 @@ func Leq[A any](O Ord[A]) func(A) func(A) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test whether one value is _strictly greater than_ another
|
* Test whether one value is strictly greater than another
|
||||||
*/
|
*/
|
||||||
func cc[A any](O Ord[A]) func(A) func(A) bool {
|
func Gt[A any](O Ord[A]) func(A) func(A) bool {
|
||||||
return func(second A) func(A) bool {
|
return func(second A) func(A) bool {
|
||||||
return func(first A) bool {
|
return func(first A) bool {
|
||||||
return O.Compare(first, second) > 0
|
return O.Compare(first, second) > 0
|
||||||
@@ -160,7 +160,7 @@ func cc[A any](O Ord[A]) func(A) func(A) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Geq tests whether one value is greater or equal than_ another
|
// Geq tests whether one value is greater or equal than another
|
||||||
func Geq[A any](O Ord[A]) func(A) func(A) bool {
|
func Geq[A any](O Ord[A]) func(A) func(A) bool {
|
||||||
return func(second A) func(A) bool {
|
return func(second A) func(A) bool {
|
||||||
return func(first A) bool {
|
return func(first A) bool {
|
||||||
|
@@ -19,9 +19,12 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
A "github.com/IBM/fp-go/array"
|
||||||
E "github.com/IBM/fp-go/either"
|
E "github.com/IBM/fp-go/either"
|
||||||
"github.com/IBM/fp-go/errors"
|
"github.com/IBM/fp-go/errors"
|
||||||
F "github.com/IBM/fp-go/function"
|
F "github.com/IBM/fp-go/function"
|
||||||
|
I "github.com/IBM/fp-go/identity"
|
||||||
|
IOE "github.com/IBM/fp-go/ioeither"
|
||||||
N "github.com/IBM/fp-go/number"
|
N "github.com/IBM/fp-go/number"
|
||||||
O "github.com/IBM/fp-go/option"
|
O "github.com/IBM/fp-go/option"
|
||||||
"github.com/IBM/fp-go/ord"
|
"github.com/IBM/fp-go/ord"
|
||||||
@@ -40,6 +43,45 @@ func getBalance(a Account) float32 {
|
|||||||
return a.Balance
|
return a.Balance
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type (
|
||||||
|
Chapter08User struct {
|
||||||
|
Id int
|
||||||
|
Name string
|
||||||
|
Active bool
|
||||||
|
Saved bool
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
albert08 = Chapter08User{
|
||||||
|
Id: 1,
|
||||||
|
Active: true,
|
||||||
|
Name: "Albert",
|
||||||
|
}
|
||||||
|
|
||||||
|
gary08 = Chapter08User{
|
||||||
|
Id: 2,
|
||||||
|
Active: false,
|
||||||
|
Name: "Gary",
|
||||||
|
}
|
||||||
|
|
||||||
|
theresa08 = Chapter08User{
|
||||||
|
Id: 3,
|
||||||
|
Active: true,
|
||||||
|
Name: "Theresa",
|
||||||
|
}
|
||||||
|
|
||||||
|
yi08 = Chapter08User{Id: 4, Name: "Yi", Active: true}
|
||||||
|
)
|
||||||
|
|
||||||
|
func (u Chapter08User) getName() string {
|
||||||
|
return u.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u Chapter08User) isActive() bool {
|
||||||
|
return u.Active
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ordFloat32 = ord.FromStrictCompare[float32]()
|
ordFloat32 = ord.FromStrictCompare[float32]()
|
||||||
UpdateLedger = F.Identity[Account]
|
UpdateLedger = F.Identity[Account]
|
||||||
@@ -55,6 +97,33 @@ var (
|
|||||||
Withdraw(20),
|
Withdraw(20),
|
||||||
O.Fold(F.Constant("You're broke!"), FinishTransaction),
|
O.Fold(F.Constant("You're broke!"), FinishTransaction),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// showWelcome :: User -> String
|
||||||
|
showWelcome = F.Flow2(
|
||||||
|
Chapter08User.getName,
|
||||||
|
S.Format[string]("Welcome %s"),
|
||||||
|
)
|
||||||
|
|
||||||
|
// checkActive :: User -> Either error User
|
||||||
|
checkActive = E.FromPredicate(Chapter08User.isActive, F.Constant1[Chapter08User](fmt.Errorf("Your account is not active")))
|
||||||
|
|
||||||
|
// validateUser :: (User -> Either String ()) -> User -> Either String User
|
||||||
|
validateUser = F.Curry2(func(validate func(Chapter08User) E.Either[error, any], user Chapter08User) E.Either[error, Chapter08User] {
|
||||||
|
return F.Pipe2(
|
||||||
|
user,
|
||||||
|
validate,
|
||||||
|
E.MapTo[error, any](user),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
// save :: User -> IOEither error User
|
||||||
|
save = func(user Chapter08User) IOE.IOEither[error, Chapter08User] {
|
||||||
|
return IOE.FromIO[error](func() Chapter08User {
|
||||||
|
var u = user
|
||||||
|
u.Saved = true
|
||||||
|
return u
|
||||||
|
})
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func Withdraw(amount float32) func(account Account) O.Option[Account] {
|
func Withdraw(amount float32) func(account Account) O.Option[Account] {
|
||||||
@@ -131,3 +200,77 @@ func Example_getAge() {
|
|||||||
// Left[*time.ParseError, float64](parsing time "July 4, 2001" as "2006-01-02": cannot parse "July 4, 2001" as "2006")
|
// Left[*time.ParseError, float64](parsing time "July 4, 2001" as "2006-01-02": cannot parse "July 4, 2001" as "2006")
|
||||||
// If you survive, you will be 6837
|
// If you survive, you will be 6837
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Example_solution08A() {
|
||||||
|
incrF := I.Map(N.Add(1))
|
||||||
|
|
||||||
|
fmt.Println(incrF(I.Of(2)))
|
||||||
|
|
||||||
|
// Output: 3
|
||||||
|
}
|
||||||
|
|
||||||
|
func Example_solution08B() {
|
||||||
|
// initial :: User -> Option rune
|
||||||
|
initial := F.Flow3(
|
||||||
|
Chapter08User.getName,
|
||||||
|
S.ToRunes,
|
||||||
|
A.Head[rune],
|
||||||
|
)
|
||||||
|
|
||||||
|
fmt.Println(initial(albert08))
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// Some[int32](65)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Example_solution08C() {
|
||||||
|
|
||||||
|
// eitherWelcome :: User -> Either String String
|
||||||
|
eitherWelcome := F.Flow2(
|
||||||
|
checkActive,
|
||||||
|
E.Map[error](showWelcome),
|
||||||
|
)
|
||||||
|
|
||||||
|
fmt.Println(eitherWelcome(gary08))
|
||||||
|
fmt.Println(eitherWelcome(theresa08))
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// Left[*errors.errorString, string](Your account is not active)
|
||||||
|
// Right[<nil>, string](Welcome Theresa)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Example_solution08D() {
|
||||||
|
|
||||||
|
// // validateName :: User -> Either String ()
|
||||||
|
validateName := F.Flow3(
|
||||||
|
Chapter08User.getName,
|
||||||
|
E.FromPredicate(F.Flow2(
|
||||||
|
S.Size,
|
||||||
|
ord.Gt(ord.FromStrictCompare[int]())(3),
|
||||||
|
), errors.OnSome[string]("Your name %s is larger than 3 characters")),
|
||||||
|
E.Map[error](F.ToAny[string]),
|
||||||
|
)
|
||||||
|
|
||||||
|
saveAndWelcome := F.Flow2(
|
||||||
|
save,
|
||||||
|
IOE.Map[error](showWelcome),
|
||||||
|
)
|
||||||
|
|
||||||
|
register := F.Flow3(
|
||||||
|
validateUser(validateName),
|
||||||
|
IOE.FromEither[error, Chapter08User],
|
||||||
|
IOE.Chain(saveAndWelcome),
|
||||||
|
)
|
||||||
|
|
||||||
|
fmt.Println(validateName(gary08))
|
||||||
|
fmt.Println(validateName(yi08))
|
||||||
|
|
||||||
|
fmt.Println(register(albert08)())
|
||||||
|
fmt.Println(register(yi08)())
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// Right[<nil>, string](Gary)
|
||||||
|
// Left[*errors.errorString, <nil>](Your name Yi is larger than 3 characters)
|
||||||
|
// Right[<nil>, string](Welcome Albert)
|
||||||
|
// Left[*errors.errorString, string](Your name Yi is larger than 3 characters)
|
||||||
|
}
|
||||||
|
@@ -17,10 +17,13 @@ package mostlyadequate
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"path"
|
||||||
|
|
||||||
A "github.com/IBM/fp-go/array"
|
A "github.com/IBM/fp-go/array"
|
||||||
F "github.com/IBM/fp-go/function"
|
F "github.com/IBM/fp-go/function"
|
||||||
|
"github.com/IBM/fp-go/io"
|
||||||
O "github.com/IBM/fp-go/option"
|
O "github.com/IBM/fp-go/option"
|
||||||
|
S "github.com/IBM/fp-go/string"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
@@ -37,20 +40,70 @@ type (
|
|||||||
AddressBook struct {
|
AddressBook struct {
|
||||||
Addresses []Address
|
Addresses []Address
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Chapter09User struct {
|
||||||
|
Id int
|
||||||
|
Name string
|
||||||
|
Address Address
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func getAddresses(ab AddressBook) []Address {
|
var (
|
||||||
|
albert09 = Chapter09User{
|
||||||
|
Id: 1,
|
||||||
|
Name: "Albert",
|
||||||
|
Address: Address{
|
||||||
|
Street: Street{
|
||||||
|
Number: 22,
|
||||||
|
Name: "Walnut St",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
gary09 = Chapter09User{
|
||||||
|
Id: 2,
|
||||||
|
Name: "Gary",
|
||||||
|
Address: Address{
|
||||||
|
Street: Street{
|
||||||
|
Number: 14,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
theresa09 = Chapter09User{
|
||||||
|
Id: 3,
|
||||||
|
Name: "Theresa",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func (ab AddressBook) getAddresses() []Address {
|
||||||
return ab.Addresses
|
return ab.Addresses
|
||||||
}
|
}
|
||||||
|
|
||||||
func getStreet(s Address) Street {
|
func (s Address) getStreet() Street {
|
||||||
return s.Street
|
return s.Street
|
||||||
}
|
}
|
||||||
|
|
||||||
var FirstAddressStreet = F.Flow3(
|
func (s Street) getName() string {
|
||||||
getAddresses,
|
return s.Name
|
||||||
A.Head[Address],
|
}
|
||||||
O.Map(getStreet),
|
|
||||||
|
func (u Chapter09User) getAddress() Address {
|
||||||
|
return u.Address
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
FirstAddressStreet = F.Flow3(
|
||||||
|
AddressBook.getAddresses,
|
||||||
|
A.Head[Address],
|
||||||
|
O.Map(Address.getStreet),
|
||||||
|
)
|
||||||
|
|
||||||
|
// getFile :: IO String
|
||||||
|
getFile = io.Of("/home/mostly-adequate/ch09.md")
|
||||||
|
|
||||||
|
// pureLog :: String -> IO ()
|
||||||
|
pureLog = io.Logf[string]("%s")
|
||||||
)
|
)
|
||||||
|
|
||||||
func Example_street() {
|
func Example_street() {
|
||||||
@@ -62,3 +115,35 @@ func Example_street() {
|
|||||||
// Output:
|
// Output:
|
||||||
// Some[mostlyadequate.Street]({Mulburry 8402})
|
// Some[mostlyadequate.Street]({Mulburry 8402})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Example_solution09A() {
|
||||||
|
// // getStreetName :: User -> Maybe String
|
||||||
|
getStreetName := F.Flow4(
|
||||||
|
Chapter09User.getAddress,
|
||||||
|
Address.getStreet,
|
||||||
|
Street.getName,
|
||||||
|
O.FromPredicate(S.IsNonEmpty),
|
||||||
|
)
|
||||||
|
|
||||||
|
fmt.Println(getStreetName(albert09))
|
||||||
|
fmt.Println(getStreetName(gary09))
|
||||||
|
fmt.Println(getStreetName(theresa09))
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// Some[string](Walnut St)
|
||||||
|
// None[string]
|
||||||
|
// None[string]
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func Example_solution09B() {
|
||||||
|
logFilename := F.Flow2(
|
||||||
|
io.Map(path.Base),
|
||||||
|
io.ChainFirst(pureLog),
|
||||||
|
)
|
||||||
|
|
||||||
|
fmt.Println(logFilename(getFile)())
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// ch09.md
|
||||||
|
}
|
||||||
|
@@ -20,7 +20,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
F "github.com/IBM/fp-go/function"
|
F "github.com/IBM/fp-go/function"
|
||||||
O "github.com/IBM/fp-go/ord"
|
"github.com/IBM/fp-go/ord"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -31,7 +31,7 @@ var (
|
|||||||
ToLowerCase = strings.ToLower
|
ToLowerCase = strings.ToLower
|
||||||
|
|
||||||
// Ord implements the default ordering for strings
|
// Ord implements the default ordering for strings
|
||||||
Ord = O.FromStrictCompare[string]()
|
Ord = ord.FromStrictCompare[string]()
|
||||||
)
|
)
|
||||||
|
|
||||||
func Eq(left string, right string) bool {
|
func Eq(left string, right string) bool {
|
||||||
@@ -42,6 +42,10 @@ func ToBytes(s string) []byte {
|
|||||||
return []byte(s)
|
return []byte(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ToRunes(s string) []rune {
|
||||||
|
return []rune(s)
|
||||||
|
}
|
||||||
|
|
||||||
func IsEmpty(s string) bool {
|
func IsEmpty(s string) bool {
|
||||||
return len(s) == 0
|
return len(s) == 0
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user