F# Creating a delegate with void return - delegates

I am trying to write a f-sharp program which should use a C#/.Net dll. The C# code looks like this:
public delegate void OnX (X x);
public delegate void OnXError (X x, string error);
public Foo(OnX onX, OnXError onXError);
My current try in F# Llooks like this:
let OnX (x:X) =
()
let OnXError (x:X) (error:sting)=
()
let foo=new Foo(OnX,OnXError)
This does not compile. OnX has type x -> unit instead of OnX. I have also tried to create the delegate in a seperate binding, but have not find a solution yet.

You can create the delegate explicitly:
let d1 = new OnX(fun (x: X) -> ())
let d2 = new OnXError(fun (x: X) (error: string) -> ())

Related

Bug in Scalajs when compiling pattern matching?

I currently cannot reproduce this in a minimum working example, but I'm working on it.
Adding a line in a dead code causes a crash at run-time.
Here are the relevant code snippets, first from the scala file:
// We are inside an object. Expr is a trait with many case classes.
case class Problem(in: Expr, out: Expr)
type RepairOutput = Either[String, Stream[Expr]]
private sealed trait RepairFinalTransform
...
private sealed trait TransformExtend extends RepairFinalTransform {
def continuation(repair: Problem => RepairOutput)
: Expr => RepairOutput
}
private case class TransformSolutionAndContinue(f: Expr => (Problem, Expr => Expr)) extends TransformExtend {
def continuation(repair: Problem => RepairOutput): Expr => RepairOutput = (x: Expr) => f(x) match {
case (p, rewriter) => repair(p) andMap rewriter
}
}
private case class TransformAndContinue(f: Expr => RepairOutput) extends TransformExtend {
def continuation(repair: Problem => RepairOutput): Expr => RepairOutput = f
}
The following code snippet
case c: TransformExtend =>
r = r andThen c.continuation(_repair)
, when working, is compiled as:
if ($is_Lexample_LambdaCalculus$TransformExtend(x1)) {
var x5 = $as_Lexample_LambdaCalculus$TransformExtend(x1);
var e$1 = r;
r = new $c_Lexample_LambdaCalculus$Retransformer().init___s_util_Either(e$1).andThen__F1__s_util_Either(x5.continuation__F1__F1(new $c_sjsr_AnonFunction1().init___sjs_js_Function1((function($this) {
return (function(original_problem$2) {
var original_problem = $as_Lexample_LambdaCalculus$Problem(original_problem$2);
return $m_Lexample_LambdaCalculus$().$$undrepair__Lexample_LambdaCalculus$Problem__s_util_Either(original_problem)
})
})(this))))
}
However, as soon as I add one occurrence of TransformAndContinue(???) (I did not have any before) in a place that is currently never executed, the above code becomes:
if ($is_Lexample_LambdaCalculus$TransformExtend(x1)) {
var x5 = $as_Lexample_LambdaCalculus$TransformExtend(x1);
var e$1 = r;
r = new $c_Lexample_LambdaCalculus$Retransformer().init___s_util_Either(e$1).andThen__F1__s_util_Either(x5.f$1)
}
Note that x5 is supposed to be a type cast to TransformExtend, which does not have the field f, only the continue method. Since f exists in both classes, its return type differs. Besides, the case class TransformSolutionAndContinue was used in many other places, so there is no reason why it calls f instead of continue.
So the translation to Javascript seems wrong (and actually, the errors fail on this point). I'm using scalajs 0.6.19 and compile using fastOptJS and scalatest.
Can you tell me what to change in my code so that the compilation is correct? Is it a known bug?

Type Provider hangs app when loading data from localhost

I have reason to believe that the type provider that I'm using is hanging my app that's running on the Android emulator.
On my main page within a Xamarin.Forms app, I have the following load operation:
protected override void OnAppearing()
{
_viewModel.Load();
return; // Never gets reached when using Type Provider...
}
My viewmodel has the following load operation:
public void Load() => Cars = new ObservableCollection<Car>(getCars());
My F# code is the following:
open FSharp.Data
// https://forums.xamarin.com/discussion/1199/how-to-make-our-remote-host-127-0-0-1-reachable-from-android-device-monoandroid-using-vs2010
[<Literal>] (* "10.0.2.2" is the workaround IP address for local host *)
let JsonPathDesignTime = "http://localhost:48213/api/cars"
let JsonPathRunTime = "http://10.0.2.2:48213/api/cars"
type Repository = JsonProvider<JsonPathDesignTime>
type Car = { Make:string ; Model:string }
let getCars() =
try
Repository.Load JsonPathRunTime
|> Array.toSeq
|> Seq.map(fun x -> { Make=x.Make ; Model=x.Model })
with error -> failwith error.Message
I did not observe any exceptions thrown with the code above. However, return to the client caller does NOT occur.
NOTE:
If I don't use a Type Provider, but instead return an empty sequence, then the app does NOT hang.
Example:
type Car = { Make:string ; Model:string }
let getCars() : Car seq =
Seq.empty

Swift - Cannot explicitly specialize a generic function

I am running into a compiler issue. It happens when I use SwiftTask, and Async, here is a sample:
//-- Generic Method
import Async
import SwiftTask
class AsyncTask {
func background<T>(job: (((Float -> Void), (T -> Void), (NSError -> Void), SwiftTask.TaskConfiguration) -> Void)) -> SwiftTask.Task<Float, T, NSError> {
return SwiftTask.Task<Float, T, NSError> { (progress: (Float -> Void), fulfill: (T -> Void), reject: (NSError -> Void), configure: SwiftTask.TaskConfiguration) -> Void in
Async.background {
job(progress, fulfill, reject, configure)
return
}
return
}
}
}
Now that compiles, but when I try to use the generic like so:
//-- Using the Generic Method
let task = AsyncTask.background<MyAwesomeObject> { progress, fulfill, reject, configure in
let obj = MyAwesomeObject()
//-- ... do work here
fulfill(obj)
return
}
I then get the following error Cannot explicitly specialize a generic function
The way you try to specialise a generic function is called explicit specialization.It’s not a syntax error, it’s a semantic error. At parse time, there’s no difference between
let x = foo<Int>()
and
let arr = Array<Int>()
But in the current version of Swift language which is 5.1 this is not permitted but in future versions it could be permited to use it.
Today, a type arguments of a generic function are always determined via type inference. For example, given:
func foo<T>()
let x = foo() as Int
// or
let x: Int = foo()
or T is determined via the argument's type. In that case an additional argument must be introduced into a method signature
func foo<T>(t: T)
let x = foo(Int.self)
Give the closure an explicit type to fix T:
let task = AsyncTask.background{ (progress: Float -> Void, fulfill: MyAwesomeObject -> Void, reject: NSError -> Void, configure: SwiftTask.TaskConfiguration) -> Void in
let obj = MyAwesomeObject()
//-- ... do work here
fulfill(obj)
}

How to properly add global NSEvent listener for pressure events in Swift OS X application?

I'm pretty new in OS X programming and I'm trying to write an application that will capture Force Click event at system-wide context.
Based on various sources I wrote down code listed below:
var lastClickStage = -1
func checkAssistanceSettings () -> Bool {
let checkOptPrompt = kAXTrustedCheckOptionPrompt.takeUnretainedValue() as NSString
let options = [checkOptPrompt: true]
let accessEnabled = AXIsProcessTrustedWithOptions(options)
return accessEnabled == 1
}
func processForceClick(incomingEvent: NSEvent!) -> Void {
let clickStage = incomingEvent.stage
if clickStage == lastClickStage {
return
}
if (lastClickStage == 2 && clickStage != 2) {
lastClickStage = clickStage
return
}
if (clickStage == 2 && lastClickStage != 2) {
let applicationClicked = NSWorkspace.sharedWorkspace().frontmostApplication?.bundleIdentifier
if (applicationClicked != nil) {
NSLog("ForceClicked in \(applicationClicked!)!")
}
lastClickStage = clickStage
}
}
func processForceClickLocally(incomingEvent: NSEvent!) -> NSEvent {
processForceClick(incomingEvent)
return incomingEvent
}
func applicationDidFinishLaunching(aNotification: NSNotification) {
NSLog("\(checkAssistanceSettings())")
NSEvent.addLocalMonitorForEventsMatchingMask(NSEventMaskFromType(NSEventType.EventTypePressure), handler: processForceClickLocally)
NSEvent.addGlobalMonitorForEventsMatchingMask(NSEventMaskFromType(NSEventType.EventTypePressure), handler: processForceClick)
}
When I run my application local event listener seems to work like a charm, but global event listener never calls his handler, even if XCode or a specific built application gets grant to accessibility in System Settings (AXIsProcessTrustedWithOptions(options) evaluates as "true").
Can anyone point out what's wrong with it?
EDIT: Even strange thing discovered by me: seems like global listener not working with this NSEventMask. Got no problem with NSEventMask.LeftMouseDownMask for example.
So now seems like question is transformed to "What wrong with NSEventMask.EventMaskPressure in global listeners?".

Can I store methods in an array?

Consider the following code:
class Test {
func func1(arg1: Int) -> Void {
println(arg1)
}
var funcArr: Array< (Int) -> Void > = [func1] // (!) 'Int' is not a subtype of 'Test'
}
I'm trying to store the method func1in an array, but as you can see, this doesn't seem to work because func1supposedly only takes an argument of type Test. I assume this has something to do with methods needing to be associated with an object.
For some more clarification, have a look at the following code where I let swift infer the type of the array:
class Test {
func func1(arg1: Int) -> Void {
println(arg1)
}
var funcArr = [func1]
}
Test().funcArr[0](Test()) // Compiles, but nothing gets printed.
Test().funcArr[0](1) // (!) Type 'Test' does not conform to protocol 'IntegerLiteralConvertible'
Test().func1(1) // Prints '1'
A possible workaround for this problem is moving func1outside of the class like so:
func func1(arg1: Int) -> Void {
println(arg1)
}
class Test {
var funcArr = [func1]
}
Test().funcArr[0](1) // Prints '1'
This works fine for this simple example, but is less than ideal when I actually need to operate on an Object of type Test in the function. I can of course add another parameter to the function to pass an instance of Testto the function, but this seems clunky.
Is there any way I can store methods in an array?
Ultimately, what I want to be able to do is testObject.funcArr[someInt](someParam) and have that function work as a method belonging to testObject. Any clever workarounds are of course also welcome.
Instance methods in swift are just curried functions, and the first argument is implicitly an instance of the class (i.e. self). And that's why these two are equivalent:
Test().func1(0)
Test.func1(Test())(0)
So when you try to put that function in the array, you're reveling its real nature: the method func1 on Test is actually this class method:
class func1(self_: Test)(arg1: Int)
So when you refer to simply func1 (without an "instance context") it has type Test -> Int -> Void, instead of the expected Int -> Void, and that's why you get the error
Int is not a subtype of Test
So the real issue is that when you store the methods in funcArr the instance is not known yet (or if you will, you're referring the function at a class level). You can work around this using a computed property:
var funcArr: [Int -> Void] { return [func1] } // use a computed property
Or another valuable option could be simply to acknowledge the real type of func1 and explicitly passing the instance. E.g.
...
var funcArr = [func1]
...
let test = Test()
let func1 = test.funcArr[0]
func1(test)(0) // prints 0
update
Freely inspired by this other Q/A (Make self weak in methods in Swift) I came up with a similar solution that stores the method references.
func weakRef<T: AnyObject, A, B>(weakSelf: T, method: T -> A -> B) -> A -> B {
return { [unowned weakSelf] in { a in method(weakSelf)(a) } }()
}
class Test {
var methodRefs: [Int -> Void] = []
init() {
methodRefs.append(weakRef(self, Test.func1))
}
func func1(arg1: Int) {
println(arg1)
}
}
In order to store a method, you should remember that the method is invoked on a class instance. What's actually stored in the array is a curried function:
(Test) -> (Int) -> Void
The first function takes a class instance and returns another function, the actual (Int) -> Void method, which is then invoked on that instance.
To make it more explicit, the array type is:
var funcArr: [(Test) -> (Int) -> Void] = [Test.func1]
Then you can invoke the method with code like this:
var test = Test()
var method = test.funcArr[0]
method(test)(1)
Suggested reading: Curried Functions

Resources