I have a protocol:
protocol MasterGame {}
and a class that produces a singleton
class MasterGameImp : MasterGame {
static let sharedInstance = MasterGameImp()
}
Now I have another object that has a dependency on the protocol and has the property injected by it's instantiator.
class MyGameObject {
var masterGame: MasterGame?
}
I want to write a unit test to test that the singleton is injected properly into an instance of MyGameObject. What is the right way to do this? === does not accept arguments of type MasterGame and MasterGameImp. So apparently you can't check sameness that way between a protocol and a class. So I need another way to check sameness between the singleton and the stored property. Thanks!
The issue very much simplified is the following:
protocol P {
}
class X : P {
}
let x = X()
let p : P = x
print(x === p)
Binary operator === cannot be applied to operands of type 'X' and 'P'
print((x as P) === p)
Binary operator === cannot be applied to two 'P' operands
print(x === (p as! X))
true -> Working
What you have to do is upcast the protocol to its implementation, which es really not pretty at all :/
I did not find a better solution, it has something to do how swift handles protocols different than regular class inheritance. Changing to class P will result in all three above statements to succeed.
As #matt noted the code will of course crash if you incorrectly provide a wrong p which is not really a X. To solve that issue you should wrap the check into a if-condition:
if let xp = p as? X {
print(x === xp)
} else {
print("p is not of type X")
}
Related
I am trying to achieve the following:
I have an interface, called IBotCommand and a few classes that implement it. I want to find all these classes, through reflection, instantiate an instance of each and put the result in a dictionary.
the interface is the following:
type IBotCommands =
abstract member Name: unit -> string
abstract member Description: unit -> string
abstract member Help: unit -> string
abstract member Execute: MessageEventArgs -> string[] -> string
and the code:
let t = typeof<IBotCommands>
t.Assembly.GetTypes()
|> Seq.filter (fun x -> x.IsSubclassOf(t))
|> Seq.iter (fun x ->
(
let i = Activator.CreateInstance(x) :> IBotCommands
botCommands.[i.Name] <- i
)
)
the issue I have is with the CreateInstance line. CreateInstance returns an obj type that can't be cast to IBotCommands.
I have the same in C# and it works properly but the C# version is using dynamics:
public static IEnumerable<Type> FindClassSubclassOfType<T>()
{
var a = typeof(T)
.Assembly.GetTypes()
.Where(t => t.IsSubclassOf(typeof(T)))
.Select(t => t);
return a.ToList();
}
var types = ReflectionHelper.FindClassSubclassOfType<BotCommand>();
foreach (var t in types)
{
dynamic c = Activator.CreateInstance(t);
BotCommands[c.Name] = c;
}
how can I get this behavior to work in F#?
can you cast an object to an interface in F#? it's my first time using interfaces in F#
In F#, there is a difference between upcast a :> T and downacst a :?> T.
Upcast is used when the compiler statically knows that a implements an interface T. This is useful if you have a value of a concrete class and want to get a value that has a type of an interface.
Downcast is used when the compiler does not statically know whether a implements an interface. In other words, this means that the cast can fail.
In your case, you need a downcast, because the compiler does not know whether obj implements IBotInterface. All you need to do is to add ?:
let i = Activator.CreateInstance(x) :?> IBotCommands
botCommands.[i.Name] <- i
Is it possible to constrain two generic parameters associated types in a function to each other?
I'm trying to do something like this:
protocol One {
associatedtype first: Two
}
protocol Two {
associatedtype second: One
}
func f<O: One, T: Two>(o: O) -> T where O.first == T, T.second == O {
fatalError()
}
It fails with the errors:
'first' is not a member type of 'O'
'second' is not a member type of 'T'
I was able to get this compile by removing one of the constraints on the function:
func f<O: One, T>(o: O) -> T where O.first == T, T.second == O {
fatalError()
}
You don't need to say that T conforms to Two because that's already implied by O.first == T (because O.first must conform to Two). Once I took that out, this compiled.
I'm trying to createa a base test class where I can setup common methods.
type BaseTest() =
member self.Assert (functionToEvaluate:bool, ?errorMessage:string) =
let a = fun () -> defaultArg errorMessage ""
match errorMessage with
| None -> NUnit.Framework.Assert.That(functionToEvaluate)
| _ -> NUnit.Framework.Assert.That(functionToEvaluate, a )
[<TestFixture>]
type MyTest () =
inherit BaseTest()
[<Test>]
member self.``test something``() =
let x = 1
self.Assert_( (x = 2))
// or
self.Assert_( (x = 2), "x value is not 2")
How to make the code "clean" (let a ... is horrible for me)
How to avoid using this/self in the derived class?
How can I write it like self.Assert(x=1) or even better just Assert(x=1) instead of self.Assert((x=1)) ?
What I want tot do (and I can do with C#) is this:
// in base test class
protected void Assert(bool test) => NUnit.Framework.Assert.That(test);
protected void Assert(bool test, string errorMessage) => NUnit.Framework.Assert.That(test, errorMessage);
// in test class
public void TestSomething() {
var x = 1
Assert(x==2)
// or
Assert(x==2, "x is not 2")
}
Your problem is that you're trying to translate the C# program into F# verbatim and expect it to look "nice" without realizing that the initial C# program is already full of C#-specific tricks that exist in order to make it look "nice". One example is the base class. Why is there a base class? Does it represent something? No, it doesn't: it's there for the sole purpose of avoiding a class name when calling these functions - i.e. you write Assert instead of SomeHelper.Assert. This stems out of the fact that in C# you can't have free-standing functions.
But in F# - you can!
let assrt x = NUnit.Framework.Assert.That(x)
let assrtWith x msg = NUnit.Framework.Assert.That(x, msg)
[<TestFixture>]
type SaleRepositoryTest () =
[<Test>]
member self.``test something``() =
let x = 1
assrt (x=2)
assrtWith (x=2) "x is not 2"
(Note that you can't use the name assert, because it's a keyword)
Also note that you generally don't need classes. The fact that in C# you can't do anything without them is a giant mistake that grows out of Java design, which was a misunderstanding of OO.
You can have free-standing functions. If I remember correctly, NUnit should be able to discover such tests just fine (though I can't verify right now):
let [<Test>] ``test something``() =
let x = 1
assrt (x=2)
assrtWith (x=2) "x is not 2"
Finally, I strongly recommend that you consider FsUnit. It can bind to NUnit (if you're locked into that) and provides a nice library of F#-idiomatic assertions.
I need clarity on how objects are declared and assigned a definition in F#.
What's happening in this code?
let service = {
new IService with
member this.Translate(_) = raise error }
My guess is we're creating an object that will implement some interface on the fly even though there is no actual class that's backing this object. Hence, we're removing the ceremony involved with creating an object by not having to declare a separate class to use it. In this case, we're minimizing the ceremony involved for implementing a mock object that could be used within a unit test.
Is my understanding accurate?
I tried to research my question and found the specification for F# 3.0 (Section - 6.3.8 Object Expressions)
6.3.8 Object Expressions An expression of the following form is an object expression: { new ty0 args-expropt object-members interface
ty1 object-members1 … interface tyn object-membersn } In the case
of the interface declarations, the object-members are optional and are
considered empty if absent. Each set of object-members has the form:
with member-defns endopt Lexical filtering inserts simulated $end
tokens when lightweight syntax is used. Each member of an object
expression members can use the keyword member, override, or default.
The keyword member can be used even when overriding a member or
implementing an interface.
For example:
let obj1 =
{ new System.Collections.Generic.IComparer<int> with
member x.Compare(a,b) = compare (a % 7) (b % 7) }
You can get a pretty good picture of what is happening behind the scenes if you look at the generated IL using a decompiler like ILSpy. For the example involving IComparer, it generates a hidden class, which implements the interface:
internal sealed class obj1#2 : IComparer<int> {
public obj1#2() : this() { }
int IComparer<int>.System-Collections-Generic-IComparer(int x, int y) {
int num = x % 7;
int num2 = y % 7;
if (num < num2) { return -1; }
return (num > num2) ? 1 : 0;
}
}
Inside the body of the method, it then creates a new instance:
IComparer<int> obj1 = new obj1#2();
When I extend a type with a new function, I usually want it to be available from both dot-notation and free form. Either can be more readable depending on the situation, and the former helps with IntelliSense while the latter helps with currying.
In C#/VB.net, extension methods do this (although I cannot restrict the function to a static method of the extended static class, as in F#). I can write the function once and then invoke it both ways:
<Extension>
public function bounded(s as string, min as UShort, max as UShort) as string
if min > max then throw new ArgumentOutOfRangeException
if string.IsNullOrEmpty(s) then return new string(" ", min)
if s.Length < min then return s.PadRight(min, " ")
if s.Length > max then return s.Substring(0, max)
return s
end function
' usage
dim b1 = bounded("foo", 10, 15)
dim b2 = "foo".bounded(0, 2)
(That's not quite perfect yet, as I'd like bounded to be a static method of String, but C#/VB.Net can't do that. Point to F# in that regard.)
In F#, on the other side, I have to declare the function separatedly from the method:
// works fine
[<AutoOpen>]
module Utilities =
type List<'T> with
member this.tryHead = if this.IsEmpty then None else Some this.Head
module List =
let tryHead (l : List<'T>) = l.tryHead
Question: Is there a more elegant way to declare both methods at once?
I tried to use:
// doesn't quite work
type List<'T> with
member this.tryHead = if this.IsEmpty then None else Some this.Head
static member tryHead(l : List<'T>) = l.tryHead
which at least would let me skip the module declaration, but while the definition compiles, it doesn't quite work - someList.tryHead is OK, but List.tryHead someList results in a Property tryHead is not static error.
Bonus question: As you can see, the static member definition requires a type annotation. However, no other type could have access to the method that was just defined. Why, then, can't the type be inferred?
I don't know of a way to declare both APIs in a single line of code, but you can get rid of the type annotations by making the function the implementation, and then defining the method it terms of the function:
[<AutoOpen>]
module Utilities =
module List =
let tryHead l = if List.isEmpty l then None else Some (List.head l)
type List<'a> with
member this.tryHead = List.tryHead this