# Comparable return type conflict?

**URL:** <https://forum.crystal-lang.org/t/comparable-return-type-conflict/3947>\
**Category:** Help & Support\
**Created:** [October 15, 2021, 9:20am UTC](https://forum.crystal-lang.org/t/comparable-return-type-conflict/3947 "2021-10-15T09:20:26Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jinn](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/jinn/32/1860_2.png) [@Jinn](https://forum.crystal-lang.org/u/Jinn)\
**Post date:** [October 15, 2021, 9:20am UTC](https://forum.crystal-lang.org/t/comparable-return-type-conflict/3947/1 "2021-10-15T09:20:26Z")

</div>

Hi all,  
I’m getting stuck on a very stupid thing - but I’m not really finding a way around it.  
Suppose I have this very simple class

```auto
class Container(T)

  @comparison_function : (T,T) -> Int32

  # in future, pass a comparison function to determine how to manage
  #def initialize(&comparison_function : (T, T) -> Int32)
  # @comparison_function = comparison_function
  #end

  def initialize
    {% raise "TypeError: #{@type.stringify} only accepts comparable entities or a sorting function." unless T <= Comparable %}
    @comparison_function = ->(a : T, b : T) { a <=> b }
  end
end

```

Basically, you create a Container and then the comparison function is set automatically to the `<=>` operator defined in container.

Except that it doesn’t compile when I try to do something like

```auto
Container(String).new
Container(Float64).new

```

Compile error is:  
`Error: instance variable '@comparison_function' of Container(String) must be Proc(String, String, (Int32 | Nil)), not Proc(String, String, Int32)`

But if I remove the nullable in the definition of the comparison function I get:  
`Error: instance variable '@comparison_function' of Container(Float64) must be Proc(Float64, Float64, Int32), not Proc(Float64, Float64, (Int32 | Nil))`

Which makes kind of sense looking at the source code (comparison with `NaN` should return `nil`) but it actually freezes me in the loop. 😕

Any suggestions on how to proceed?  
The only way around it that I can think of is changing the implementation from  
` @comparison_function = ->(a : T, b : T) { a <=> b }`  
to  
` @comparison_function = ->(a : T, b : T) { a <=> b || Int32::Max}`

But it’s really a meh-ing solution…  
Any better options?

---

<div class="post-metadata">

**Author:** ![jgaskins](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/jgaskins/32/2449_2.png) [@jgaskins](https://forum.crystal-lang.org/u/jgaskins)\
**Post date:** [October 15, 2021, 11:49am UTC](https://forum.crystal-lang.org/t/comparable-return-type-conflict/3947/2 "2021-10-15T11:49:49Z")

</div>

The way it’s handled for array sorting (which is implemented in `Slice` since `Array` converts itself to a slice to be sorted) is to raise if the result of the comparison is `nil`, which removes it from the return type union. Your default block could be implemented similarly.

> <https://github.com/crystal-lang/crystal/blob/9f90efe3315eba17685bb628b8b3e4713f00db5d/src/slice/sort.cr#L198-L208>
