Runtime assertions for Ruby literal.fun
ruby
5
fork

Configure Feed

Select the types of activity you want to include in your feed.

More changes

+223 -171
+4 -4
README.md
··· 149 149 attribute :thing, _Any 150 150 ``` 151 151 152 - To make this argument optional and allow `nil`, you could use use `_Maybe`. 152 + To make this argument optional and allow `nil`, you could use use `_Nilable`. 153 153 154 - ### `_Maybe(T)` 154 + ### `_Nilable(T)` 155 155 156 - The `_Maybe` type is a union of `nil` and the specified type `T`. It’s literally `_Union(T, nil)`. 156 + The `_Nilable` type is a union of `nil` and the specified type `T`. It’s literally `_Union(T, nil)`. 157 157 158 158 ```ruby 159 - attribute :thing, _Maybe(_Any) 159 + attribute :thing, _Nilable(_Any) 160 160 ``` 161 161 162 162 ### `_Boolean`
+5 -29
lib/literal/either.rb
··· 1 1 # frozen_string_literal: true 2 2 3 3 class Literal::Either 4 - def initialize(left_type, right_type) 5 - @left_type = left_type 6 - @right_type = right_type 7 - end 8 - 9 - def inspect 10 - "Either(#{@left_type.inspect}, #{@right_type.inspect})" 11 - end 12 - 13 - def ===(either) 14 - case either 15 - when Literal::Left 16 - @left_type === either.value 17 - when Literal::Right 18 - @right_type === either.value 19 - else 20 - false 21 - end 4 + def initialize(value) 5 + @value = value 6 + freeze 22 7 end 23 8 24 - def new(value) 25 - case value 26 - when @left_type 27 - Literal::Left.new(value) 28 - when @right_type 29 - Literal::Right.new(value) 30 - else 31 - raise Literal::TypeError, 32 - "Expected `#{value.inspect}` to be either `#{@left_type.inspect}` or `#{@right_type.inspect}`." 33 - end 34 - end 9 + attr_reader :value 10 + attr_accessor :type 35 11 end
-11
lib/literal/either/option.rb
··· 1 - # frozen_string_literal: true 2 - 3 - class Literal::Either::Option 4 - def initialize(value) 5 - @value = value 6 - freeze 7 - end 8 - 9 - attr_reader :value 10 - attr_accessor :type 11 - end
+35
lib/literal/either_type.rb
··· 1 + # frozen_string_literal: true 2 + 3 + class Literal::EitherType 4 + def initialize(left_type, right_type) 5 + @left_type = left_type 6 + @right_type = right_type 7 + end 8 + 9 + def inspect 10 + "Either(#{@left_type.inspect}, #{@right_type.inspect})" 11 + end 12 + 13 + def ===(either) 14 + case either 15 + when Literal::Left 16 + @left_type === either.value 17 + when Literal::Right 18 + @right_type === either.value 19 + else 20 + false 21 + end 22 + end 23 + 24 + def new(value) 25 + case value 26 + when @left_type 27 + Literal::Left.new(value) 28 + when @right_type 29 + Literal::Right.new(value) 30 + else 31 + raise Literal::TypeError, 32 + "Expected `#{value.inspect}` to be either `#{@left_type.inspect}` or `#{@right_type.inspect}`." 33 + end 34 + end 35 + end
+1 -1
lib/literal/failure.rb
··· 1 1 # frozen_string_literal: true 2 2 3 - class Literal::Failure < Literal::Result::Option 3 + class Literal::Failure < Literal::Result 4 4 def initialize(value) 5 5 @value = case value 6 6 when StandardError
+1 -1
lib/literal/left.rb
··· 1 1 # frozen_string_literal: true 2 2 3 - class Literal::Left < Literal::Either::Option 3 + class Literal::Left < Literal::Either 4 4 def left? = true 5 5 def right? = false 6 6
+33
lib/literal/maybe_type.rb
··· 1 + # frozen_string_literal: true 2 + 3 + class Literal::MaybeType 4 + def initialize(type) 5 + @type = type 6 + end 7 + 8 + def inspect 9 + "Maybe(#{@type.inspect})" 10 + end 11 + 12 + def new(value) 13 + case value 14 + when nil 15 + Literal::Nothing 16 + when @type 17 + Literal::Some.new(value) 18 + else 19 + raise Literal::TypeError, "Expected `#{value.inspect}` to be `#{@type.inspect}`." 20 + end 21 + end 22 + 23 + def ===(maybe) 24 + case maybe 25 + when Literal::Nothing 26 + true 27 + when Literal::Some 28 + @type === maybe.value 29 + else 30 + false 31 + end 32 + end 33 + end
+13 -19
lib/literal/monads.rb
··· 1 1 # frozen_string_literal: true 2 2 3 3 module Literal::Monads 4 - Nothing = Literal::Nothing.new 5 - Optional = Nothing # `Maybe` called without anything, e.g. `Maybe(something)` is Nothing 6 - 7 - def Some(thing) 8 - Literal::Some.new(thing) 9 - end 4 + Nothing = Literal::Nothing 5 + Left = Literal::Left 6 + Right = Literal::Right 7 + Some = Literal::Some 10 8 11 - def Optional(value) 12 - value.nil? ? Nothing : Some(value) 9 + def Maybe(type) 10 + Literal::MaybeType.new(type) 13 11 end 14 12 15 13 def Either(left_type, right_type) 16 - Literal::Either.new(left_type, right_type) 17 - end 18 - 19 - def Left(value) 20 - Literal::Left.new(value) 14 + Literal::EitherType.new(left_type, right_type) 21 15 end 22 16 23 - def Right(value) 24 - Literal::Right.new(value) 17 + def Result(type) 18 + Literal::ResultType.new(type) 25 19 end 26 20 27 - def Result(type) 28 - Literal::Result.new(type) 21 + def Try(type, &block) 22 + Literal::ResultType.new(type).try(&block) 29 23 end 30 24 31 - def Try(type, &) 32 - Literal::Result.new(type).try(&) 25 + def Some(type) 26 + Literal::SomeType.new(type) 33 27 end 34 28 end
+2 -28
lib/literal/nothing.rb
··· 1 1 # frozen_string_literal: true 2 2 3 - class Literal::Nothing < Literal::Optional::Option 4 - def initialize 5 - freeze 6 - end 7 - 8 - def empty? = true 9 - def inspect = "Nothing" 10 - 11 - def value_or(fallback) 12 - fallback 13 - end 14 - 15 - def map 16 - self 17 - end 18 - 19 - def flat_map 20 - self 21 - end 22 - 23 - def or_else(alternative) 24 - if alternative.nil? 25 - self 26 - else 27 - Some(alternative) 28 - end 29 - end 30 - end 3 + Literal::Nothing = Literal::NothingClass.new 4 + Literal.private_constant(:NothingClass)
+34
lib/literal/nothing_class.rb
··· 1 + # frozen_string_literal: true 2 + 3 + class Literal::NothingClass < Literal::Maybe 4 + def initialize 5 + freeze 6 + end 7 + 8 + def empty? = true 9 + def inspect = "Nothing" 10 + 11 + def value_or(fallback) 12 + fallback 13 + end 14 + 15 + def map 16 + self 17 + end 18 + 19 + def flat_map 20 + self 21 + end 22 + 23 + def or(alternative) 24 + if alternative.nil? 25 + raise Literal::TypeError, "Alternative cannot be nil." 26 + end 27 + 28 + if alternative.nil? 29 + self 30 + else 31 + Literal::Some.new(alternative) 32 + end 33 + end 34 + end
-22
lib/literal/optional.rb
··· 1 - # frozen_string_literal: true 2 - 3 - class Literal::Optional 4 - def initialize(type) 5 - @type = type 6 - end 7 - 8 - def inspect 9 - "Optional(#{@type.inspect})" 10 - end 11 - 12 - def ===(optional) 13 - case optional 14 - when Literal::None 15 - true 16 - when Literal::Some 17 - @type === optional.value 18 - else 19 - false 20 - end 21 - end 22 - end
+1 -1
lib/literal/optional/option.rb lib/literal/maybe.rb
··· 1 1 # frozen_string_literal: true 2 2 3 - class Literal::Optional::Option 3 + class Literal::Maybe 4 4 include Literal::Monads 5 5 end
+2 -30
lib/literal/result.rb
··· 1 1 # frozen_string_literal: true 2 2 3 3 class Literal::Result 4 - def initialize(type) 5 - @type = type 6 - end 7 - 8 - def inspect 9 - "Result(#{@type.inspect})" 10 - end 11 - 12 - def new(value) 13 - case value 14 - when @type 15 - Literal::Success.new(value) 16 - else 17 - Literal::Failure.new(value) 18 - end 19 - end 20 - 21 - def try 22 - output = yield 23 - if @type === output 24 - Literal::Success.new(output) 25 - else 26 - Literal::Failure.new( 27 - Literal::TypeError.new( 28 - "Expected `#{output.inspect}` to be a `#{@type.inspect}`." 29 - ) 30 - ) 31 - end 32 - rescue StandardError => e 33 - Literal::Failure.new(e) 4 + def initialize(value) 5 + @value = value 34 6 end 35 7 end
-7
lib/literal/result/option.rb
··· 1 - # frozen_string_literal: true 2 - 3 - class Literal::Result::Option 4 - def initialize(value) 5 - @value = value 6 - end 7 - end
+35
lib/literal/result_type.rb
··· 1 + # frozen_string_literal: true 2 + 3 + class Literal::ResultType 4 + def initialize(type) 5 + @type = type 6 + end 7 + 8 + def inspect 9 + "Result(#{@type.inspect})" 10 + end 11 + 12 + def new(value) 13 + case value 14 + when @type 15 + Literal::Success.new(value) 16 + else 17 + Literal::Failure.new(value) 18 + end 19 + end 20 + 21 + def try 22 + output = yield 23 + if @type === output 24 + Literal::Success.new(output) 25 + else 26 + Literal::Failure.new( 27 + Literal::TypeError.new( 28 + "Expected `#{output.inspect}` to be a `#{@type.inspect}`." 29 + ) 30 + ) 31 + end 32 + rescue StandardError => e 33 + Literal::Failure.new(e) 34 + end 35 + end
+1 -1
lib/literal/right.rb
··· 1 1 # frozen_string_literal: true 2 2 3 - class Literal::Right < Literal::Either::Option 3 + class Literal::Right < Literal::Either 4 4 def left? = false 5 5 def right? = true 6 6
+5 -5
lib/literal/some.rb
··· 1 1 # frozen_string_literal: true 2 2 3 - class Literal::Some < Literal::Optional::Option 3 + class Literal::Some < Literal::Maybe 4 4 def initialize(value) 5 5 @value = value 6 6 freeze ··· 16 16 end 17 17 18 18 def map 19 - Some(yield @value) 19 + Literal::Some.new(yield @value) 20 20 end 21 21 22 - def flat_map 23 - map(yield(@value)).value_or(Nothing) 22 + def flat_map(&block) 23 + map(&block).value_or(Nothing) 24 24 end 25 25 26 - def or_else(_alternative) 26 + def or(_alternative) 27 27 self 28 28 end 29 29 end
+29
lib/literal/some_type.rb
··· 1 + # frozen_string_literal: true 2 + 3 + class Literal::SomeType 4 + def initialize(type) 5 + @type = type 6 + end 7 + 8 + def inspect 9 + "Some(#{@type.inspect})" 10 + end 11 + 12 + def ===(other) 13 + case other 14 + when Literal::Some 15 + @type === other.value 16 + else 17 + false 18 + end 19 + end 20 + 21 + def new(value) 22 + case value 23 + when @type 24 + Literal::Some.new(value) 25 + else 26 + raise Literal::TypeError, "Expected `#{value.inspect}` to be `#{@type.inspect}`." 27 + end 28 + end 29 + end
+1 -1
lib/literal/success.rb
··· 1 1 # frozen_string_literal: true 2 2 3 - class Literal::Success < Literal::Result::Option 3 + class Literal::Success < Literal::Result 4 4 def failure? = false 5 5 def success? = true 6 6
+1 -1
lib/literal/types.rb
··· 31 31 Literal::Types::InterfaceType.new(*methods) 32 32 end 33 33 34 - def _Maybe(type) 34 + def _Nilable(type) 35 35 _Union(type, nil) 36 36 end 37 37
+10 -10
test/literal/either.rb
··· 8 8 let def left = either.new(1) 9 9 let def right = either.new("foo") 10 10 11 - test "left" do 12 - expect(left).to_be :left? 13 - expect(right).not_to_be :left? 14 - end 15 - 16 - test "right" do 17 - expect(right).to_be :right? 18 - expect(left).not_to_be :right? 19 - end 20 - 21 11 test "===" do 22 12 assert either === left 23 13 assert either === right ··· 27 17 28 18 refute either === Literal::Left.new("foo") 29 19 refute either === Literal::Right.new(1) 20 + end 21 + 22 + test "#left?" do 23 + expect(left).to_be :left? 24 + expect(right).not_to_be :left? 25 + end 26 + 27 + test "#right?" do 28 + expect(right).to_be :right? 29 + expect(left).not_to_be :right? 30 30 end 31 31 end
+10
test/literal/maybe.rb
··· 1 + # frozen_string_literal: true 2 + 3 + extend Literal::Monads 4 + 5 + User = Struct.new(:name, :address) 6 + Address = Struct.new(:street, :city, :state, :zip) 7 + 8 + user = User.new("Bob", Address.new("123 Main", "Anytown", "CA", "12345")) 9 + 10 + binding.irb