Skip to content

Instantly share code, notes, and snippets.

@Pitometsu
Created May 11, 2019 18:50
Show Gist options
  • Save Pitometsu/b180d522723d2c3ea35dbac8a6880810 to your computer and use it in GitHub Desktop.
Save Pitometsu/b180d522723d2c3ea35dbac8a6880810 to your computer and use it in GitHub Desktop.
OCaml OOP problem
class virtual semigroup = object(self : 'self)
method virtual private size : int
method plus : 'other. (#semigroup as 'other) -> int = fun other -> self#size + other#size
end;;
Error: The universal type variable 'other cannot be generalized:
it escapes its scope.
@Pitometsu
Copy link
Author

Looks like I found a workaround, isn't it?

module rec S : sig
  class virtual semigroup : object
    method virtual private size : int
    method plus : S.other -> int
  end
  type other = { instance : 'other. #S.semigroup as 'other }
end = struct
  class virtual semigroup = object(self : 'self)
    method virtual private size : int
    method plus : S.other -> int = fun other -> self#size + other.instance#size
  end
  type other = { instance : 'other. #S.semigroup as 'other }
end;;
module rec S :
  sig
    class virtual semigroup :
      object method plus : S.other -> int method private virtual size : int end
    type other = { instance : 'a. #S.semigroup as 'a; }
  end

@Pitometsu
Copy link
Author

But there's still usage problem:

class one = object
 inherit S.semigroup
 method private size = 1
end;;
class one : object method plus : S.other -> int method private size : int end

class two = object
 inherit S.semigroup
 method private size = 2
end;;
class two : object method plus : S.other -> int method private size : int end

(new one)#plus { instance = new two };;
Error: This field value has type two which is less general than
         'a. #S.semigroup as 'a

@Pitometsu
Copy link
Author

Pitometsu commented May 11, 2019

Sad, but simpler expression didn't work:

class virtual a = object(self : 'self)
  method virtual private size : int
  method plus : 'other. (< 'self; .. > as 'other) -> int = fun other -> self#size + other#size
end;;
Error: The type 'self is not an object type

UPD: not type, but type variable, that's why ^^^

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment