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])
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return func(second A) func(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 {
|
||||
return func(second A) func(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(first A) bool {
|
||||
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 {
|
||||
return func(second A) func(A) bool {
|
||||
return func(first A) bool {
|
||||
|
@@ -19,9 +19,12 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
A "github.com/IBM/fp-go/array"
|
||||
E "github.com/IBM/fp-go/either"
|
||||
"github.com/IBM/fp-go/errors"
|
||||
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"
|
||||
O "github.com/IBM/fp-go/option"
|
||||
"github.com/IBM/fp-go/ord"
|
||||
@@ -40,6 +43,45 @@ func getBalance(a Account) float32 {
|
||||
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 (
|
||||
ordFloat32 = ord.FromStrictCompare[float32]()
|
||||
UpdateLedger = F.Identity[Account]
|
||||
@@ -55,6 +97,33 @@ var (
|
||||
Withdraw(20),
|
||||
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] {
|
||||
@@ -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")
|
||||
// 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 (
|
||||
"fmt"
|
||||
"path"
|
||||
|
||||
A "github.com/IBM/fp-go/array"
|
||||
F "github.com/IBM/fp-go/function"
|
||||
"github.com/IBM/fp-go/io"
|
||||
O "github.com/IBM/fp-go/option"
|
||||
S "github.com/IBM/fp-go/string"
|
||||
)
|
||||
|
||||
type (
|
||||
@@ -37,20 +40,70 @@ type (
|
||||
AddressBook struct {
|
||||
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
|
||||
}
|
||||
|
||||
func getStreet(s Address) Street {
|
||||
func (s Address) getStreet() Street {
|
||||
return s.Street
|
||||
}
|
||||
|
||||
var FirstAddressStreet = F.Flow3(
|
||||
getAddresses,
|
||||
A.Head[Address],
|
||||
O.Map(getStreet),
|
||||
func (s Street) getName() string {
|
||||
return s.Name
|
||||
}
|
||||
|
||||
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() {
|
||||
@@ -62,3 +115,35 @@ func Example_street() {
|
||||
// Output:
|
||||
// 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"
|
||||
|
||||
F "github.com/IBM/fp-go/function"
|
||||
O "github.com/IBM/fp-go/ord"
|
||||
"github.com/IBM/fp-go/ord"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -31,7 +31,7 @@ var (
|
||||
ToLowerCase = strings.ToLower
|
||||
|
||||
// Ord implements the default ordering for strings
|
||||
Ord = O.FromStrictCompare[string]()
|
||||
Ord = ord.FromStrictCompare[string]()
|
||||
)
|
||||
|
||||
func Eq(left string, right string) bool {
|
||||
@@ -42,6 +42,10 @@ func ToBytes(s string) []byte {
|
||||
return []byte(s)
|
||||
}
|
||||
|
||||
func ToRunes(s string) []rune {
|
||||
return []rune(s)
|
||||
}
|
||||
|
||||
func IsEmpty(s string) bool {
|
||||
return len(s) == 0
|
||||
}
|
||||
|
Reference in New Issue
Block a user