Why this type is not an Interface? - interface

I want to make an interface with default implementation for equality and comparison functions.
If I remove everything from the type IKeyable<'A> except the Key member, it is a valid interface, as long as I don't add a default implementation. Removing the other interface implementations from IKeyable<'A>, and leaving just default members ends in the same result.
type IKeyable<'A when 'A: equality and 'A :> IComparable> =
abstract member Key : 'A
default this.Equals obj = // hidden for clarity
default this.GetHashCode () = // hidden for clarity
interface IEquatable<'A> with
member this.Equals otherKey = // hidden for clarity
interface IComparable<'A> with
member this.CompareTo otherKey = // hidden for clarity
interface IComparable with
member this.CompareTo obj = // hidden for clarity
type Operation =
{ Id: Guid }
interface IKeyable<Guid> with // Error: The type 'IKeyable<Guid>' is not an interface type
member this.Key = this.Id
I would like to make use of IKeyable<'A> as an interface in order to "gain" the default implementations for equality and comparison.
The error message comes up on the interface ... with under the type Operation: The type 'IKeyable<Guid>' is not an interface type

An interface cannot have method implementations, and your type has five of them - Equals, GetHashCode, IEquatable<_>.Equals, IComparable<_>.CompareTo, and IComparable.CompareTo.
An interface is purely a set of method and properties. It's not like a base class, it cannot give the implementor some "default" implementations or base behavior or utility methods it anything like that.
To make your type an interface, get rid of all the implementations:
type IKeyable<'A when 'A: equality and 'A :> IComparable> =
inherit IEquatable<'A>
inherit IComparable<'A>
abstract member Key : 'A
If you really want to keep the default implementations, you have to make it a base class rather than interface, in which case Operation must become a class rather than a record:
type Operation(id: Guid)
inherit IKeyable<Guid>
override this.Key = id
member val Id = id

Related

How to force a val in a class to be immutable in class using class type in OCaml

Let's say I have this :
class type point_t =
object
val x : int
method getx : int
method move : int -> unit
end;;
I can write a class like this and it will work :
class point : point_t =
object
val mutable x = 0
method getx = x
method move d = x <- x + d
end;;
Now suppose that I want to create a class type that would NOT allow a class to be defined with a mutable val x (I want x to be immutable). Is there a way to do that ?
It is not possible, so if you don't want to allow implementations to use a mutable variable it is better just to hide it all and expose functional getter/setter:
class type point_t = object(self)
method get_x : int
method with_x : int -> self
method move : int -> self
end;;
You may omit with_x method if you want to allow updates only via the move method.
The reasoning for this is that a class with a mutable version of a variable is a proper subclass of a class with immutable version of the same variable, as it has the same set of operations, plus one more - an ability to set the variable. So, any abstraction over a type point_t can be applied to a class instance with and without a mutability (although it will not be able to mutate the variable). Note, that the opposite is not possible, if you will define the class type point_t with a mutable x, and will try to implement it with an immutable one, then the type system will complain. As your implementation doesn't provide all the operations.
Also, there is one thing that you possibly miss. Although, the class point has a mutable variable x this mutability is actually sealed (i.e., hidden) by the type constraint point_t. So, no matter what is the implementation, the interface is strictly defined to have immutable x:
class the_point = object
inherit point
method! move d = x <- x - d
end
method! move d = x <- x - d
^^^^^^^^^^
Error: The instance variable x is not mutable
Your confusion may arise from the fact that you have some experience with Java/C++ style of OOP, where class types are nominal, and a class can became a subclass of another class only by explicit inheritance. In OCaml a class is a subclass of another class if it is a syntactical superset of it, i.e., if it has at least all fields of the super class. There is no need to inherit from a super class, to become its subclass. And class point : point_t is not an inheritance, but a type constraint, that says: here is the class expression, that implements point_t class (and maybe more), please, make sure that it is true and expose only point_t interface to the outsiders.
And a final note, I've specifically denoted term sub classing as the syntactic super set of a super class to emphasize the fact that inheritance and sub classing do not imply subtyping. The latter is the semantics (i.e., the behavior of an instance), the former is syntax, i.e., a set of code fragments. Subclassing gives you a code reuse, the ability to copy the code from superclasses (as inherit is actually just copy/pasting the code of super class to your sub class). The subtyping gives you the polymorphism - an ability to use the same abstraction on different implementations.

What does => mean at the beginning of a Scala class definition?

The author of the question
Exchanging type parameters with abstract types wrote a => at the beginning of his class definitions. Example:
abstract class Thing { t =>
type A
type G <: Group { type A = t.A }
val group: G
}
What does the t => mean ?
Because this is hard to find in Google & Co, can someone please give me more background information or provide a link, where I can find more information about this language construct ?
The default naming for class itself is this. You may replace it with t by t =>
It is useful if your class contains subclasses and you need access to enclosing self reference.
Without t => in your example you would write something like this:
abstract class Thing {
type G <: Group { type A = this.A }
}
Group { type A = this.A } is a subtype so this would reference to group specialization itself not to a thing object. Probably you get not what you mean to get. If you need access to Thing self reference you should resolve name conflict by assigning self reference another name
abstract class Thing { another_this = >
type G <: Group { type A = another_this.A}
}
It is indeed self type annotation. See the official Scala specification:
https://scala-lang.org/files/archive/spec/2.13/13-syntax-summary.html
According to this specification, its context free EBNF syntax is:
SelfType ::= id [‘:’ Type] ‘=>’
| ‘this’ ‘:’ Type ‘=>’
So, basically, this means SelfType has two basic forms. In one form, you can use an id with or without Type. In the other, you can use this but it must be accompanied with a Type.
You can find it in section 29.4 of Programming in Scala Second Edition. However, remember that books can be quickly out of date, so you need to refer to the specification.

Puzzle -- exposing a public sub-member of private member with custom type

I would like to do something like this (example is simplified, but contains all the crucial pieces):
class Master
{
type DataType = Int
var counter : DataType = 0
}
class Slave(private val master : Master)
{
val counter = master.counter // (*)
}
And here (*) I get error:
private value master escapes its defining scope as part of type
Slave.this.master.DataType
val counter = master.counter
I understand the error, but I don't understand the reason - the type is part of the class Master, not the object master, so it is important if the class is private, not an object. Well, at least in theory.
It is easy to make a quick workaround:
val counter : Master#DataType = master.counter
But I believe this is an explicit version of the exactly same code as before, it "only" takes more typing. Is this a feature then?
QUESTION:
Can a type (here DataType) be dependent of the object, and not the class (i.e. type definition per instance of the class) in Scala?
You are wrong when you think
this is an explicit version of the exactly same code as before
Master#DataType and master.DataType are two different types.
master.DataType is the type of those DataType instances which have master as outer object. In other words, precisely what you ask, but obviously then master is part of the type, and the type can't be exposed if master isn't.
Master#DataType is the type of any DataType instance for any outer object (equivalent to Master.DataType in Java).
REPLY TO THE COMMENT:
Type members can be overridden in a subclass (including an anonymous subclass containing only one object), but only by a compatible type. And in your example DataType is already concrete in Master, so the only compatible class with it is itself. So something like
val a = new Master {
override type DataType = String
}
won't typecheck, which makes sense: you'd get var counter: String = 0, which is nonsense. But
val a = new Master {
override type DataType = Int
}
will work (but isn't too useful).
So it only ever makes sense to override abstract type members. But they are type-checked in the same way as inner classes, so a.DataType is not generally considered the same as b.DataType -- even if they can't actually be different!

Creating and using a generic function in a non generic F# interface

It is beyond me at this point. I'm trying to create an interface that looks something like
this.
type IFetchData =
abstract FetchData: string -> seq<'a>
The above declaration is valid (and compiles) but when I go to use it I get a compile time error. This expression was expected to have type 'a but here has type "what I'm currently trying to return" i.e. seq.
My example usage however looks like the following:
type SampleFetchData() =
interface IFetchData with
member self.FetchData str =
seq {
for letter in str do
yield letter // compile error here
}
I'm not sure what I'm doing wrong. All I'd like to do is allow the interface implementer to be able to write any function that returns a generic sequence either seq<string>,seq<int>,seq<record type here>, seq<union type here>, etc.
Can someone tell me what I'm missing here?
Thanks.
If you're loading the interface implementation using Reflection, then it is going to be quite difficult to work with it. The problem is that you get an object of type obj. You know that it implements IFetchData<'T> for some 'T, but statically, you don't know for which 'T. This is a problem because you can't cast the object to any more specific type - if you tried using IFetchData<obj>, it wouldn't work because you can't cast, for example, IFetchData<int> to that type.
I would recommend using a non-generic interface, which is quite common .NET pattern:
type IFetchDataUntyped =
abstract FetchData : string -> System.Collections.IEnumerable
type IFetchData<'T> =
inherit IFetchDataUntyped
abstract FetchData : string -> seq<'T>
When you load an implementation using Reflection, you can cast the object to IFetchDataUntyped and work with it in a fairly reasonable way (using Seq.cast to convert the sequence to a more specific type if you know the element type).
Depending on your application, you may also just make the FetchData method a generic method and keep the interface non-generic. Then you could cast dynamically loaded objects to the interface and invoke the method. However, this changes the design (because the method has to work for any type it gets as a type parameter):
type IFetchData =
abstract FetchData<'T> : string -> seq<'T> // Note: Generic parameter here!
You need to do something like
type IFetchData<'a> =
abstract FetchData: string -> seq<'a>
type SampleFetchData() =
interface IFetchData<char> with
member self.FetchData str =
seq {
for letter in str do
yield letter
}
i.e. the interface needs to be made generic. If you want to avoid the genericness you could use some inline constraints, rather than an interface
EDIT: Inline magic version
let inline Fetchdata string obj=
(^a: (member FetchData: string -> seq<'b> )(obj, string))
type SampleFetchData() =
member self.FetchData str =
seq {
for letter in str do
yield letter
}
Fetchdata "hello" (new SampleFetchData())

OCaml types with different levels of specificity

I am attempting to simulate an interface in OCaml and am using the "type" construct. I have two types:
type fooSansBar = {a: string; b: int};;
type fooConBar = {a:string; b:int; bar:char};;
...and would like to define a particular fooSansBar:
let fsb = {a="a"; b=3};;
...but am told that the bar field is not defined. From this, it appears that, contrary to the values I passed in matching fooSansBar's signature, the system believes I am trying to create a fooConBar. Is it possible to create a fooSansBar if the two types as defined above exist?
Additionally (because I'm new to OCaml) is there a better way to simulate an interface?
In OCaml, field names in record types must be unique, so the two types you define cannot coexist simultaneously. Caml is the only language I know with this property.
Because the second definition hides the first, when the compiler sees the a and b fields it expects them to belong to the fooConBar type and so complains of the missing bar field.
If you are trying to simulate an interface, the correct functional way to do it in Caml is to define a module type.
module type FOO_CON_BAR = sig
val a : string
val b : int
val bar : char
end
And an instance:
module Example = struct
let a = "hello"
let b = 99
let c = '\n'
end
With modules and module types you also get subtyping; there's no need to resort to objects.
P.S. My Caml is rusty; syntax may be off.
There are several possible solutions in OCaml depending how you're using the code you gave. The simplest is to combine the two types:
type fooBar = { a: string; b: int; bar: char option }
Another solution is to replace the records with objects because objects support subtyping (and can have their types inferred so there is no need to declare a type!):
# let fsb = object
method a = "a"
method b = 3
end;;
val fsb : < a : string; b : int > = <obj>
# fsb#a, fsb#b;;
- : string * int = ("a", 3)
The second type redefines a and b, effectively hiding the first, which is why it cannot be constructed any more. You could define these types in different modules, but that would be the same as using a different name for a and b.
These constructs can only be used when you do not try to "derive" from another interface, but just implement it.
If you wish to use these object oriented concepts in Ocaml, you could look at the object system, or, depending on your problem, the module system. Alternatively, you could try to solve your problem in a functional way. What problem are you trying to solve?
OCaml provides two ways to implement interfaces. One, as already mentioned, is a module type.
The other is a class type. You can write a class type (interface) fooSansBar:
class type fooSansBar = object
method a: string
method b: int
end
and a class type fooConBar:
class type fooConBar = object
inherit fooSansBar
method bar: char
end
This will allow you to use a fooConBar anywhere a fooSansBar is required. You can now create a fooSansBar, using type inference:
let fsb = object
method a = "a"
method b = 3
end
Now, fsb's type happens to be <a: string; b: int>, as indicated by Jon, but it's perfectly usable as a fooSansBar due to OCaml's structural subtyping.
In OCaml, it's not possible to have two record types with intersecting field sets present in the same scope.
If you really need to use record types with intersecting field sets, then you can work around this restriction by enclosing the types within their own dedicated modules:
module FooSansBar = struct type t = {a:string; b:int} end
module FooConBar = struct type t = {a:string; b:int; bar:char} end
Then you can construct instances of these types like so:
let fsb = {FooSansBar.a="a"; b=3}
let fcb = {FooConBar.a="a"; b=4; bar='c'}
These instances have the following types:
fsb : FooSansBar.t
fcb : FooConBar.t