How would this class look in f#?
public class myClass : baseClass
{
public myClass()
{
this.someVariable = "test";
this.someFunction();
}
}
So far i've figured out (is it even correct?):
type myClass = class
inherit baseClass
new ()=
this.someFunction()
end
but am struggling with calling someFunction() as it says 'this' is not defined
Here's one way to translate your code:
type baseClass() =
member this.someFunction() = printf "hello world\n"
type myClass() as this =
inherit baseClass()
let mutable someVariable = "test"
do this.someFunction()
Related
Reading the "Substituting types" section from "The Dart type system" I don't understand why I get the error from assigning from one level above from hierarchy.
class Animal { }
class Cat extends Animal { }
class MaineCoon extends Cat { }
Animal c = Cat(); works to the compiler, but MaineCoon c = Cat(); get incorrect constructor error.
I don't understand why MaineCoon couldn't be cast to Cat, but Animal can cast
Cat or even Animal c = MaineCoon(); still works.
Short answer (see source code below)
void main() {
Animal animal = Cat();
print(animal.animalName);
MaineCoon maineCoon = Cat();
// Opps!!! The "Cat" does not declares "maineCoonName".
print(maineCoon.maineCoonName);
}
class Animal {
String animalName = 'animal';
}
class Cat extends Animal {
String catName = 'cat';
}
class MaineCoon extends Cat {
String maineCoonName = 'maineCoonName';
}
How do you imagine accessing maineCoonName from instance Cat if Cat did not declare a member maineCoonName?
P.S.
Even if this member (I mean maineCoonName) is not declared, this does not mean that a similar member will not be added in the future, which, in principle, will break the entire program.
Is it possible for an object to refer to itself before member definitions? Something like this:
type public ClassA () = class
let b = new ClassB(this)
member public x.getClassB() = b
end
where 'this' is a reference to the instance of ClassA creating the ClassB?
Classes can refer to themselves in their constructors using as:
type public ClassA () as this =
let b = new ClassB(this)
member public x.getClassB() = b
and public ClassB (a: ClassA) =
member public x.getClassA() = a
Given we have a Swift protocol with one static method:
protocol Creatable: class {
static func create() -> AnyObject
}
and a pure Swift class which conforms to the protocol:
class Foo : Creatable {
static func create() -> AnyObject {
return Foo() as AnyObject
}
}
Later on when one tries to make use of that protocol by operating on type Creatable e.g.:
var f : Creatable = Foo.self
f.create()
The compiler complains with the following:
error: type 'Foo.Type' does not conform to protocol 'Creatable'
The question is: is this a Swift limitation or I'm using the protocols and static/class method in the wrong way.
Objective-C equivalent would be something like:
Class someClass = [Foo class];
if ([someClass conformsToProtocol:#protocol(Creatable)]) {
[(Class <Foo>)someClass create];
}
A Creatable reference points to an instance of Foo, not to the Foo type itself.
To get the equivalent of the class-level protocol implementation, you need an instance of Creatable.Type:
let c: Creatable.Type = Foo.self
However, you’ll get an error when you then try to use it:
// error: accessing members of protocol type value 'Creatable.Type' is unimplemented
c.create()
All that said, is there a reason why you can’t just use functions to fulfill your requirement, instead of metatypes?
let f = Foo.create
// f is now a function, ()->AnyObject, that creates Foos
let someFoo = f()
Using .Type is the key:
var f : Creatable.Type = Foo.self
And this no longer gives the "unimplemented" error. See full code below:
protocol Creatable: class {
static func create() -> AnyObject
}
class Foo : Creatable {
static func create() -> AnyObject {
return Foo() as AnyObject
}
}
var f : Creatable.Type = Foo.self
f.create()
I am having difficulty to convert following C# code to F#:
class Foo
{
public Foo() { }
public Foo(string name) { }
}
class Bar : Foo
{
public Bar() : base() { }
public Bar(string name) : base(name) { }
public string Name { get; set; }
}
I first tried following, but it is reporting error
Constructors for the type 'Bar' must directly or indirectly call its
implicit object constructor. Use a call to the implicit object
constructor instead of a record expression.
type Foo() =
new(name:string) = Foo()
type Bar() =
inherit Foo()
new(name:string) = { inherit Foo(name) }
member val Name:string = null with get, set
Then I tried following, but it is now reporting error on the auto property
'member val' definitions are only permitted in types with a primary
constructor. Consider adding arguments to your type definition"
type Foo() =
new(name:string) = Foo()
type Bar =
inherit Foo
new(name:string) = { inherit Foo(name) }
member val Name:string = null with get, set
If you want F# source code who compiles to precisely the same API as given by your C# code, the answer is as follows:
type Foo =
new() = {}
new(name:string) = { }
type Bar =
inherit Foo
[<DefaultValue>]
val mutable private name:string
new() = { inherit Foo() }
new(name) = { inherit Foo(name) }
member x.Name with get() = x.name and set v = x.name <- v
This compiles:
type Foo() =
new(name:string) = Foo()
type Bar(name : string) =
inherit Foo()
new() = Bar(null) // or whatever you want as a default.
member val Name:string = name with get, set
See Constructors (F#) and Inheritance (F#).
Looking at the decompilation, the C# would be (with attributes removed):
public class Bar : Program.Foo {
internal string Name#;
public string Name {
get {
return this.Name#;
}
set {
this.Name# = value;
}
}
public Bar(string name) {
this.Name# = name;
}
public Bar() : this(null) {
}
}
public class Foo {
public Foo() {
}
public Foo(string name) : this() {
}
}
If a class has a parameter list directly after its name (including ()), it has a primary constructor. Using it, any inherit declarations are placed only in this primary constructor, which comes directly after the class declaration and before any member declarations.
It is unclear what you are trying to achieve. The class Foo has a constructor taking a string argument, only to discard it. A (technically) valid, similar pair of classes would be this:
type Foo(name:string) =
member f.NameLength = name.Length
type Bar(initialName) = // WARNING: this will not end well
inherit Foo(initialName)
member val Name:string = initialName with get, set
But this is not sensible code. Foo will keep the initial name even if the name in Bar is changed. Bar.Name.Length returns the current name's length, while Bar.NameLength returns the initial name's length.
To keep the default constructor, one could add new () = Bar(null) (or the equivalent in Foo), but please note that null is considered an interop-only feature. It is not used in F# facing code; if possible, use the appropriate option type or an empty string respectively (depending on whether the string is just empty or doesn't exist at all).
Also, inheriting classes is discouraged in the F# component design guidelines -- for good reason. There are few use cases, but those usually involve a tiny base class and a derived class that is a perfect superset of it. It is far more common to compose types by using one class as a member of another.
I don't know how relevant this is, but here is an example of a class with default constructor and an additional constructor that uses it:
type Text500(text : string) =
do if text.Length > 500 then
invalidArg "text" "Text of this type cannot have a length above 500."
member t.Text = text
new () = Text500("")
This utilizes the primary constructor to verify input and has an additional, parameterless constructor that uses an empty string. (I'm not sure if the additional constructor would be useful in actual applications.)
Suppose I have this situation:
class Foo {
final _bar;
Foo([bar = 'hello']);
}
In Dart, how do I initialize _bar, given that it's private?
You can use the initializer list.
class Foo {
final _bar;
Foo([bar = 'hello']) : _bar = bar;
}
The initializer list is run before the constructor body.