Class: Proc
Instance Attribute Summary collapse
-
#is_tupled ⇒ Object
Returns the value of attribute is_tupled.
Class Method Summary collapse
Instance Method Summary collapse
- #*(lamb) ⇒ Object
-
#**(lamb) ⇒ Object
<*> from Control.Applicative.
- #+(lamb) ⇒ Object
- #<<(val) ⇒ Object
- #>>(lamb) ⇒ Object
-
#[](*args) ⇒ Object
Just a friendly reminder .() is shorthand for .call() and self.arity is the number of arguments this Proc takes.
-
#^(lamb) ⇒ Object
<**> from Control.Applicative.
- #bind(lamb) ⇒ Object
- #call(*args) ⇒ Object
- #fmap(lamb) ⇒ Object
- #standard_ruby_call ⇒ Object
- #|(lamb) ⇒ Object
Instance Attribute Details
#is_tupled ⇒ Object
Returns the value of attribute is_tupled.
4 5 6 |
# File 'lib/raskell/proc.rb', line 4 def is_tupled @is_tupled end |
Class Method Details
.pure(arg) ⇒ Object
10 11 12 |
# File 'lib/raskell/proc.rb', line 10 def self.pure(arg) ->(x) { arg } end |
Instance Method Details
#*(lamb) ⇒ Object
62 63 64 65 66 67 68 69 70 |
# File 'lib/raskell/proc.rb', line 62 def *(lamb) # You, then me # like function composition if lamb.class != Proc lamb | self else ->(x) { self.( lamb.( x ) ) } end end |
#**(lamb) ⇒ Object
<*> from Control.Applicative
14 15 16 |
# File 'lib/raskell/proc.rb', line 14 def **(lamb) ## <*> from Control.Applicative ->(x) { self.(x, lamb.(x)) } end |
#+(lamb) ⇒ Object
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/raskell/proc.rb', line 82 def +(lamb) ## later need to check if they have the same arity, once I've fixed the arity function to handle nesting lambdas this = self result = ->(xs) { if lamb.is_tupled && this.is_tupled this.(xs) + lamb.(xs) elsif lamb.is_tupled [this.(xs)] + lamb.(xs) elsif this.is_tupled this.(xs) + [lamb.(xs)] else [this.(xs),lamb.(xs)] end } result.is_tupled = true result end |
#<<(val) ⇒ Object
101 102 103 104 |
# File 'lib/raskell/proc.rb', line 101 def <<(val) # feed data from the right self.(val.()) end |
#>>(lamb) ⇒ Object
106 107 108 109 |
# File 'lib/raskell/proc.rb', line 106 def >>(lamb) # feed data from the left, assuming I am a wrapped Object of some sort lamb.(self.()) end |
#[](*args) ⇒ Object
Just a friendly reminder .() is shorthand for .call() and self.arity is the number of arguments this Proc takes
32 33 34 |
# File 'lib/raskell/proc.rb', line 32 def [](*args) call(*args) end |
#^(lamb) ⇒ Object
<**> from Control.Applicative
20 21 22 |
# File 'lib/raskell/proc.rb', line 20 def ^(lamb) ->(x) { lamb.(self.(x), x) } end |
#bind(lamb) ⇒ Object
24 25 26 |
# File 'lib/raskell/proc.rb', line 24 def bind(lamb) ->(x) { lamb.(self.(x), x)} end |
#call(*args) ⇒ Object
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/raskell/proc.rb', line 36 def call(*args) args_to_consume = args.take(self.arity < 0 ? self.arity.abs : self.arity) ## the < 1 here is because ruby stores *args as an arity of one more than the required args, in a negative number remaining_args = args.drop(self.arity < 0 ? self.arity.abs : self.arity) if !args_to_consume.respond_to?(:length) ## then we're dealing with a *args-only lambda, and we have enough args. just apply them all result = self.standard_ruby_call(*args) elsif self.arity == 0 result = self.standard_ruby_call() elsif args.length == 0 #interpret application with no arguments on a non-zero-arity function as a no-op return self elsif (self.arity < 0 && args.length >= self.arity.abs - 1) ## then we're dealing with a *args-based lambda, and we have enough args. just apply them all result = self.standard_ruby_call(*args) elsif args_to_consume.length < self.arity #if you have too few arguments, return a lambda asking for more before attempting to re-apply return ->(x) { self.call( *( args + [x] ) ) } elsif self.arity < 0 return ->(*xs) { self.call( *( args + xs.deep_clone ) ) } else #otherwise, apply the arguments result = self.standard_ruby_call(*args_to_consume) end # if the result is a proc, make sure to unwrap further by recursively calling with any remaining arguments (result.kind_of?(Proc) && remaining_args.length > 0) || (result.kind_of?(Proc) && remaining_args.length == 0 && result.respond_to?(:arity) && result.arity == 0) ? result.call(*remaining_args) : result end |
#fmap(lamb) ⇒ Object
6 7 8 |
# File 'lib/raskell/proc.rb', line 6 def fmap(lamb) self * lamb end |
#standard_ruby_call ⇒ Object
3 |
# File 'lib/raskell/proc.rb', line 3 alias_method :standard_ruby_call, :call |
#|(lamb) ⇒ Object
72 73 74 75 76 77 78 79 80 |
# File 'lib/raskell/proc.rb', line 72 def |(lamb) # Me, then you # like unix pipes if lamb.class != Proc lamb * self else ->(x) { lamb.( self.( x ) ) } end end |