Last active
December 29, 2015 11:19
-
-
Save sunaku/7663078 to your computer and use it in GitHub Desktop.
Example of the functional approach to problem decomposition in Ruby.
https://class.coursera.org/proglang-002/forum/thread?thread_id=1962
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
BadResult = Class.new Exception | |
Int = Struct.new :i | |
Negate = Struct.new :e1 | |
Add = Struct.new :e1, :e2 | |
def eval e | |
case e | |
when Int then e | |
when Negate then case v1 = (eval e.e1) | |
when Int then Int.new -v1.i | |
else raise BadResult, "non-int in negation" | |
end | |
when Add then case v1 = (eval e.e1) | |
when Int then case v2 = (eval e.e2) | |
when Int then Int.new v1.i + v2.i | |
end | |
end or raise BadResult, "non-int in negation" | |
else raise ArgumentError, e | |
end | |
end | |
def toString e | |
case e | |
when Int then e.i.to_s | |
when Negate then "-(" + (toString e.e1) + ")" | |
when Add then "(" + (toString e.e1) + " + " + (toString e.e2) + ")" | |
else raise ArgumentError, e | |
end | |
end | |
def hasZero e | |
case e | |
when Int then e.i == 0 | |
when Negate then hasZero e.e1 | |
when Add then hasZero e.e1 or hasZero e.e2 | |
else raise ArgumentError, e | |
end | |
end | |
def noNegConstants e | |
case e | |
when Int then if e.i < 0 then Negate.new Int.new -e.i else e end | |
when Negate then Negate.new noNegConstants e.e1 | |
when Add then Add.new (noNegConstants e.e1), (noNegConstants e.e2) | |
else raise ArgumentError, e | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ ruby -r ./section8.rb -e 'p (toString (Add.new (Int.new 5), (Add.new (Negate.new (Int.new 3)), (Int.new 8))))' | |
"(5 + (-(3) + 8))" | |
$ ruby -r ./section8.rb -e 'p (eval (Add.new (Int.new 5), (Add.new (Negate.new (Int.new 3)), (Int.new 8))))' | |
#<struct Int i=10> | |
$ ruby -r ./section8.rb -e 'p (hasZero (Add.new (Int.new 5), (Add.new (Negate.new (Int.new 3)), (Int.new 8))))' | |
false | |
$ ruby -r ./section8.rb -e 'p (toString (Add.new (Int.new -5), (Int.new -3)))' | |
"(-5 + -3)" | |
$ ruby -r ./section8.rb -e 'p (toString (noNegConstants (Add.new (Int.new -5), (Int.new -3))))' | |
"(-(5) + -(3))" | |
$ ruby -r ./section8.rb -e 'p (eval (Add.new (Int.new 5), "hello"))' | |
./section8.rb:19:in `eval': hello (ArgumentError) | |
from ./section8.rb:15:in `eval' | |
from -e:1:in `' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment