mirror of
https://github.com/IBM/fp-go.git
synced 2025-06-17 00:07:49 +02:00
285 lines
8.5 KiB
Go
285 lines
8.5 KiB
Go
// 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 cli
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
|
|
A "github.com/IBM/fp-go/array"
|
|
F "github.com/IBM/fp-go/function"
|
|
N "github.com/IBM/fp-go/number"
|
|
S "github.com/IBM/fp-go/string"
|
|
)
|
|
|
|
var (
|
|
concStrgs = A.Monoid[string]().Concat
|
|
intercalStrgs = A.Intercalate(S.Monoid)
|
|
concAllStrgs = A.ConcatAll(A.Monoid[string]())
|
|
)
|
|
|
|
func joinAll(middle string) func(all ...[]string) string {
|
|
ic := intercalStrgs(middle)
|
|
return func(all ...[]string) string {
|
|
return ic(concAllStrgs(all))
|
|
}
|
|
}
|
|
|
|
func generateGenericSequenceT(
|
|
nonGenericType func(string) string,
|
|
genericType func(string) string,
|
|
extra []string,
|
|
) func(f, fg *os.File, i int) {
|
|
return func(f, fg *os.File, i int) {
|
|
// tuple
|
|
tuple := tupleType("T")(i)
|
|
// all types T
|
|
typesT := A.MakeBy(i, F.Flow2(
|
|
N.Inc[int],
|
|
S.Format[int]("T%d"),
|
|
))
|
|
// non generic version
|
|
fmt.Fprintf(f, "\n// SequenceT%d converts %d [%s] into a [%s]\n", i, i, nonGenericType("T"), nonGenericType(tuple))
|
|
fmt.Fprintf(f, "func SequenceT%d[%s any](\n", i, joinAll(", ")(extra, typesT))
|
|
for j := 0; j < i; j++ {
|
|
fmt.Fprintf(f, " t%d %s,\n", j+1, nonGenericType(fmt.Sprintf("T%d", j+1)))
|
|
}
|
|
fmt.Fprintf(f, ") %s {\n", nonGenericType(tuple))
|
|
fmt.Fprintf(f, " return G.SequenceT%d[\n", i)
|
|
fmt.Fprintf(f, " %s,\n", nonGenericType(tuple))
|
|
for j := 0; j < i; j++ {
|
|
fmt.Fprintf(f, " %s,\n", nonGenericType(fmt.Sprintf("T%d", j+1)))
|
|
}
|
|
fmt.Fprintf(f, " ](")
|
|
for j := 0; j < i; j++ {
|
|
if j > 0 {
|
|
fmt.Fprintf(f, ", ")
|
|
}
|
|
fmt.Fprintf(f, "t%d", j+1)
|
|
}
|
|
fmt.Fprintf(f, ")\n")
|
|
fmt.Fprintf(f, "}\n")
|
|
|
|
// generic version
|
|
fmt.Fprintf(fg, "\n// SequenceT%d converts %d [%s] into a [%s]\n", i, i, genericType("T"), genericType(tuple))
|
|
fmt.Fprintf(fg, "func SequenceT%d[\n", i)
|
|
fmt.Fprintf(fg, " G_TUPLE%d ~%s,\n", i, genericType(tuple))
|
|
for j := 0; j < i; j++ {
|
|
fmt.Fprintf(fg, " G_T%d ~%s, \n", j+1, genericType(fmt.Sprintf("T%d", j+1)))
|
|
}
|
|
fmt.Fprintf(fg, " %s any](\n", joinAll(", ")(extra, typesT))
|
|
for j := 0; j < i; j++ {
|
|
fmt.Fprintf(fg, " t%d G_T%d,\n", j+1, j+1)
|
|
}
|
|
fmt.Fprintf(fg, ") G_TUPLE%d {\n", i)
|
|
fmt.Fprintf(fg, " return A.SequenceT%d(\n", i)
|
|
// map call
|
|
var cio string
|
|
cb := generateNestedCallbacks(1, i)
|
|
if i > 1 {
|
|
cio = genericType(cb)
|
|
} else {
|
|
cio = fmt.Sprintf("G_TUPLE%d", i)
|
|
}
|
|
fmt.Fprintf(fg, " Map[%s],\n", joinAll(", ")(A.From("G_T1", cio), extra, A.From("T1", cb)))
|
|
// the apply calls
|
|
for j := 1; j < i; j++ {
|
|
if j < i-1 {
|
|
cb := generateNestedCallbacks(j+1, i)
|
|
cio = genericType(cb)
|
|
} else {
|
|
cio = fmt.Sprintf("G_TUPLE%d", i)
|
|
}
|
|
fmt.Fprintf(fg, " Ap[%s, %s, G_T%d],\n", cio, genericType(generateNestedCallbacks(j, i)), j+1)
|
|
}
|
|
// function parameters
|
|
for j := 0; j < i; j++ {
|
|
fmt.Fprintf(fg, " t%d,\n", j+1)
|
|
}
|
|
|
|
fmt.Fprintf(fg, " )\n")
|
|
fmt.Fprintf(fg, "}\n")
|
|
}
|
|
}
|
|
|
|
func generateGenericSequenceTuple(
|
|
nonGenericType func(string) string,
|
|
genericType func(string) string,
|
|
extra []string,
|
|
) func(f, fg *os.File, i int) {
|
|
return func(f, fg *os.File, i int) {
|
|
// tuple
|
|
tuple := tupleType("T")(i)
|
|
// all types T
|
|
typesT := A.MakeBy(i, F.Flow2(
|
|
N.Inc[int],
|
|
S.Format[int]("T%d"),
|
|
))
|
|
// non generic version
|
|
fmt.Fprintf(f, "\n// SequenceTuple%d converts a [T.Tuple%d[%s]] into a [%s]\n", i, i, nonGenericType("T"), nonGenericType(tuple))
|
|
fmt.Fprintf(f, "func SequenceTuple%d[%s any](t T.Tuple%d[", i, joinAll(", ")(extra, typesT), i)
|
|
for j := 0; j < i; j++ {
|
|
if j > 0 {
|
|
fmt.Fprintf(f, ", ")
|
|
}
|
|
fmt.Fprintf(f, "%s", nonGenericType(fmt.Sprintf("T%d", j+1)))
|
|
}
|
|
fmt.Fprintf(f, "]) %s {\n", nonGenericType(tuple))
|
|
fmt.Fprintf(f, " return G.SequenceTuple%d[\n", i)
|
|
fmt.Fprintf(f, " %s,\n", nonGenericType(tuple))
|
|
for j := 0; j < i; j++ {
|
|
fmt.Fprintf(f, " %s,\n", nonGenericType(fmt.Sprintf("T%d", j+1)))
|
|
}
|
|
fmt.Fprintf(f, " ](t)\n")
|
|
fmt.Fprintf(f, "}\n")
|
|
|
|
// generic version
|
|
fmt.Fprintf(fg, "\n// SequenceTuple%d converts a [T.Tuple%d[%s]] into a [%s]\n", i, i, genericType("T"), genericType(tuple))
|
|
fmt.Fprintf(fg, "func SequenceTuple%d[\n", i)
|
|
fmt.Fprintf(fg, " G_TUPLE%d ~%s,\n", i, genericType(tuple))
|
|
for j := 0; j < i; j++ {
|
|
fmt.Fprintf(fg, " G_T%d ~%s, \n", j+1, genericType(fmt.Sprintf("T%d", j+1)))
|
|
}
|
|
fmt.Fprintf(fg, " %s any](t T.Tuple%d[", joinAll(", ")(extra, typesT), i)
|
|
for j := 0; j < i; j++ {
|
|
if j > 0 {
|
|
fmt.Fprintf(fg, ", ")
|
|
}
|
|
fmt.Fprintf(fg, "G_T%d", j+1)
|
|
}
|
|
fmt.Fprintf(fg, "]) G_TUPLE%d {\n", i)
|
|
fmt.Fprintf(fg, " return A.SequenceTuple%d(\n", i)
|
|
// map call
|
|
var cio string
|
|
cb := generateNestedCallbacks(1, i)
|
|
if i > 1 {
|
|
cio = genericType(cb)
|
|
} else {
|
|
cio = fmt.Sprintf("G_TUPLE%d", i)
|
|
}
|
|
fmt.Fprintf(fg, " Map[%s],\n", joinAll(", ")(A.From("G_T1", cio), extra, A.From("T1", cb)))
|
|
// the apply calls
|
|
for j := 1; j < i; j++ {
|
|
if j < i-1 {
|
|
cb := generateNestedCallbacks(j+1, i)
|
|
cio = genericType(cb)
|
|
} else {
|
|
cio = fmt.Sprintf("G_TUPLE%d", i)
|
|
}
|
|
fmt.Fprintf(fg, " Ap[%s, %s, G_T%d],\n", cio, genericType(generateNestedCallbacks(j, i)), j+1)
|
|
}
|
|
// function parameters
|
|
fmt.Fprintf(fg, " t)\n")
|
|
fmt.Fprintf(fg, "}\n")
|
|
}
|
|
}
|
|
|
|
func generateGenericTraverseTuple(
|
|
nonGenericType func(string) string,
|
|
genericType func(string) string,
|
|
extra []string,
|
|
) func(f, fg *os.File, i int) {
|
|
return func(f, fg *os.File, i int) {
|
|
// tuple
|
|
tupleT := tupleType("T")(i)
|
|
tupleA := tupleType("A")(i)
|
|
// all types T
|
|
typesT := A.MakeBy(i, F.Flow2(
|
|
N.Inc[int],
|
|
S.Format[int]("T%d"),
|
|
))
|
|
// all types A
|
|
typesA := A.MakeBy(i, F.Flow2(
|
|
N.Inc[int],
|
|
S.Format[int]("A%d"),
|
|
))
|
|
// all function types
|
|
typesF := A.MakeBy(i, F.Flow2(
|
|
N.Inc[int],
|
|
func(j int) string {
|
|
return fmt.Sprintf("F%d ~func(A%d) %s", j, j, nonGenericType(fmt.Sprintf("T%d", j)))
|
|
},
|
|
))
|
|
// non generic version
|
|
fmt.Fprintf(f, "\n// TraverseTuple%d converts a [T.Tuple%d[%s]] into a [%s]\n", i, i, nonGenericType("T"), nonGenericType(tupleT))
|
|
fmt.Fprintf(f, "func TraverseTuple%d[%s any](", i, joinAll(", ")(typesF, extra, typesA, typesT))
|
|
for j := 0; j < i; j++ {
|
|
if j > 0 {
|
|
fmt.Fprintf(f, ", ")
|
|
}
|
|
fmt.Fprintf(f, "f%d F%d", j+1, j+1)
|
|
}
|
|
fmt.Fprintf(f, ") func(%s) %s {\n", tupleA, nonGenericType(tupleT))
|
|
fmt.Fprintf(f, " return G.TraverseTuple%d[%s](", i, nonGenericType(tupleT))
|
|
for j := 0; j < i; j++ {
|
|
if j > 0 {
|
|
fmt.Fprintf(f, ", ")
|
|
}
|
|
fmt.Fprintf(f, "f%d", j+1)
|
|
}
|
|
fmt.Fprintf(f, ")\n")
|
|
fmt.Fprintf(f, "}\n")
|
|
|
|
// generic version
|
|
fmt.Fprintf(fg, "\n// TraverseTuple%d converts a [T.Tuple%d[%s]] into a [%s]\n", i, i, genericType("T"), genericType(tupleT))
|
|
fmt.Fprintf(fg, "func TraverseTuple%d[\n", i)
|
|
fmt.Fprintf(fg, " G_TUPLE%d ~%s,\n", i, genericType(tupleT))
|
|
for j := 0; j < i; j++ {
|
|
fmt.Fprintf(fg, " F%d ~func(A%d) G_T%d,\n", j+1, j+1, j+1)
|
|
}
|
|
for j := 0; j < i; j++ {
|
|
fmt.Fprintf(fg, " G_T%d ~%s, \n", j+1, genericType(fmt.Sprintf("T%d", j+1)))
|
|
}
|
|
fmt.Fprintf(fg, " %s any](", joinAll(", ")(extra, typesA, typesT))
|
|
for j := 0; j < i; j++ {
|
|
if j > 0 {
|
|
fmt.Fprintf(fg, ", ")
|
|
}
|
|
fmt.Fprintf(fg, "f%d F%d", j+1, j+1)
|
|
}
|
|
fmt.Fprintf(fg, ") func(%s) G_TUPLE%d {\n", tupleA, i)
|
|
fmt.Fprintf(fg, " return func(t %s) G_TUPLE%d {\n", tupleA, i)
|
|
fmt.Fprintf(fg, " return A.TraverseTuple%d(\n", i)
|
|
// map call
|
|
var cio string
|
|
cb := generateNestedCallbacks(1, i)
|
|
if i > 1 {
|
|
cio = genericType(cb)
|
|
} else {
|
|
cio = fmt.Sprintf("G_TUPLE%d", i)
|
|
}
|
|
fmt.Fprintf(fg, " Map[%s],\n", joinAll(", ")(A.From("G_T1", cio), extra, A.From("T1", cb)))
|
|
// the apply calls
|
|
for j := 1; j < i; j++ {
|
|
if j < i-1 {
|
|
cb := generateNestedCallbacks(j+1, i)
|
|
cio = genericType(cb)
|
|
} else {
|
|
cio = fmt.Sprintf("G_TUPLE%d", i)
|
|
}
|
|
fmt.Fprintf(fg, " Ap[%s, %s, G_T%d],\n", cio, genericType(generateNestedCallbacks(j, i)), j+1)
|
|
}
|
|
// function parameters
|
|
for j := 0; j < i; j++ {
|
|
fmt.Fprintf(fg, " f%d,\n", j+1)
|
|
}
|
|
// tuple parameter
|
|
fmt.Fprintf(fg, " t)\n")
|
|
fmt.Fprintf(fg, " }\n")
|
|
fmt.Fprintf(fg, "}\n")
|
|
}
|
|
}
|