Skip to content

Instantly share code, notes, and snippets.

@svanellewee
Last active August 29, 2015 14:06
Show Gist options
  • Select an option

  • Save svanellewee/933641e3c805bf035719 to your computer and use it in GitHub Desktop.

Select an option

Save svanellewee/933641e3c805bf035719 to your computer and use it in GitHub Desktop.
Simple Monad Experiment
20 [10.000000, was multiplied by 2]
23 [10.000000, was added to 13]
24 [12.000000, was multiplied by 2]
37 [12.000000, was multiplied by 2][24.000000, was added to 13]
56 [15.000000, was + 13][28.000000, was X2]
/*
Converted Haskell to Go, first example from http://blog.sigfpe.com/2006/08/you-could-have-invented-monads-and.html
*/
package main
import ( "fmt" )
type inputfunc func(float64) float64;
// f :: Float -> Float
func f(x float64) float64 {
return x + 13
}
// g :: Float -> Float
func g(x float64) float64 {
return x * 2
}
// (Float -> (Float, String))
type liftedfunc func(float64) (float64, string);
// lift ::( (Float -> Float), String) -> (Float -> (Float, String))
func lift(ifunc inputfunc,descr string) (result liftedfunc){
result = func(x float64) (float64, string) {
return ifunc(x),fmt.Sprintf("[%f, %s]",x, descr);
}
return
}
// called 'unit' because go already reserves "return"
func unit(x float64) (float64, string) {
return x,""
}
type chainedfunc func(float64, string) (float64, string);
// bind :: (Float -> (Float, String)) -> ((Float, String) -> (Float, String))
func bind(ifunc liftedfunc ) (result chainedfunc) {
result = func(x float64, descr string) (float64, string) {
cur_value, cur_descr := ifunc(x)
new_description := descr + cur_descr
return cur_value, new_description
}
return
}
type func_descr struct {
function inputfunc
description string
}
func chain(initvalue float64, function_description []func_descr) (float64, string) {
previous_result, previous_description := unit(initvalue)
for _,fdes := range function_description {
function, description := fdes.function, fdes.description
chainable_function := bind(lift(function,description))
previous_result, previous_description = chainable_function(previous_result, previous_description)
}
return previous_result, previous_description
}
func main(){
fmt.Println("this is spartaa!!!")
g_prime := lift(g, " was multiplied by 2")
f_prime := lift(f, " was added to 13")
fmt.Println(g_prime(10))
fmt.Println(f_prime(10))
//fmt.Println(bind(f_prime)(12,"hello"))
fmt.Println(bind(g_prime)(unit(12)));
/*
Haskell code syntax might be wrong...
the gist of what I want is :
return 12 >>= (\x -> (2 * x," was multiplied by 3")) >>= (\x -> (13 + x," was added to 13") )
*/
fmt.Println(bind(f_prime)(bind(g_prime)(unit(12))))
// not very readable.. refactor, use chain!!
fmt.Println(chain(15, []func_descr { { f,"was + 13"},
{ g,"was X2" }}))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment