Skip to content

Instantly share code, notes, and snippets.

@AlecAivazis
Created May 23, 2017 20:38
Show Gist options
  • Save AlecAivazis/80e7c8a25a9d2efb38c3f77c15658161 to your computer and use it in GitHub Desktop.
Save AlecAivazis/80e7c8a25a9d2efb38c3f77c15658161 to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"reflect"
)
// Value an interface for anything with a value.
type Value interface {
Value() interface{}
}
type Just struct {
val interface{}
}
func (j *Just) Value() interface{} {
return j.val
}
type FunctorMap func(Value) Value
type Functor interface {
Map(FunctorMap) Functor
}
type FunctorList []Value
func (f *FunctorList) Map(fn FunctorMap) Functor {
// the list we are going to build up
result := FunctorList{}
// for each entry in the list we are converting
for _, entry := range *f {
entry := entry.(*Just).Value().(reflect.Value)
result = append(result, fn(&Just{entry}))
}
return &result
}
func FunctorFromList(list interface{}) FunctorList {
// the list we are going to build up
result := FunctorList{}
switch reflect.TypeOf(list).Kind() {
case reflect.Slice:
s := reflect.ValueOf(list)
for i := 0; i < s.Len(); i++ {
result = append(result, &Just{s.Index(i)})
}
}
return result
}
func main() {
// the string slice we're messing with
slice := []string{"hello world", "goodbye moon"}
// create a list of functors from the list of string
functors := FunctorFromList(slice)
// the function to apply to each entry/
f := func(val Value) Value {
return &Just{len(val.Value().(reflect.Value).String())}
}
for _, i := range *(functors.Map(f).(*FunctorList)) {
fmt.Println(i.Value())
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment