f# function not recognized as parameter - f#

Please unwrap these type signatures to help me understand why this doesn't work.
Then, if you have a solution, that would be great too.
I have this code and the agent.Post command has the signature Observer.Create<'T>(onNext: Action<'T>) : IObserver<'T>
let reservatinoRequestObserver = Observer.Create agent.Post
interface IHttpControllerActivator with
To my knowledge, this means that Observer.Create should take an Action with a single generic parameter and then return an IObserver.
Now the definition of Post is member MailboxProcessor.Post : message:'Msg ->unit
So... Post is a method, no? It is a method that takes a single parameter no? And it returns void no? So shouldn't it be a candidate for Observer.Create? Isn't that the exact specification of Action<'T>?
Well, somethings up, I get This function takes too many arguments, or is used in a context where a function is not expected:
Help me out... I freely admit I suck at F#

First, agent.Post returns unit, which is a different thing from void. F# will usually convert back and forth between void and unit for you, but they are not the same thing.
Second, F# functions do not implicitly convert to .NET delegates.
But there are some ways to do it:
You can explicitly create the delegate using its constructor:
let o = Observer.Create (new Action<_>( agent.Post ))
Lambdas are nicely wrapped too
let o = Observer.Create (fun msg -> agent.Post msg)
Use F# Rx-wrappers
Also there are a couple of F# wrappers/interop for Rx on nuget - just have a look, I think any will do

Related

Pass value to second parameter in a pipeline

what's the correct way to pass a value to the second paramater of a function in a pipeline?
e.g.
async {
let! response =
someData
|> JsonConvert.SerializeObject
|> fun x -> new StringContent(x)
|> httpClient.PostAsync "/DoSomething"
|> Async.AwaitTask
}
in the above code PostAsync takes 2 parameters, the url to post to and the content you want to post. Have tried the back pipe too, and parenthesis, but cant quite figure out how to do it
any ideas?
PostAsync has non-curried parameters, which cannot be passed in one by one, they have to be passed all at once. This is why you should always have your parameters curried.
But alas, you can't control the definition of PostAsync, because it's a .NET library method, so you have to wrap it one way or another. There are a few options:
Option 1: use a lambda expression:
|> fun body -> httpClient.PostAsync( "/DoSomething", body )
Option 2: declare yourself a function with curried parameters
let postAsync client url body =
client.PostAsync(url, body)
...
|> postAsync httpClient "/DoSomething"
This is usually my preferred option: I always wrap .NET APIs in F# form before using them. This is better, because the same wrapper can transform more than just parameters, but also other things, such as error handling or, in your case, async models:
let postAsync client url body =
client.PostAsync(url, body)
|> Async.AwaitTask
Option 3: go super general and make yourself a function for transforming any functions from non-curried to curried. In other functional languages such function is usually called uncurry:
let uncurry f a b = f (a, b)
...
|> uncurry httpClient.PostAsync "/DoSomething"
One problem with this is that it only works for two parameters. If you have a non-curried function with three parameters, you'd have to create a separate uncurry3 function for it, and so on.
In F#, you often need to work with .NET APIs that are not designed to work well as functional pipelines. In those cases, you can do various tricks to fit it into an (often very ugly) pipeline, or you can use the fact that F# is multi-paradigm and write the code in a more object-oriented style.
In your example, I would just use more C#-like style, because the code is not very pipeline-friendly:
async {
let serialized = JsonConvert.SerializeObject(someData)
let postData = new StringContent(serialized)
let! response = httpClient.PostAsync("/DoSomething", postData) |> Async.AwaitTask
}
I think there is also a good theoretical reason why this should not be a pipe - typically, pipelines work well if you have some "main entity" that you are transforming through a series of operations. This can often be some generic type such as list<'a> or non-generic type like Chart.
In your example, you start with object, turn it into JSON, then turn that into StringContent, then Task<'T> etc. - in other words, it's not transforming an entity - it's just doing a lot of unrelated things. In those situations, I prefer to use more explicit coding style rather than pipe.

Unable to use protected events in F#

Let's say we have the following C# class
public class Class1
{
protected event EventHandler ProtectedEvent;
protected virtual void OverrideMe() { }
}
It seems to be impossible to use the ProtectedEvent in F#.
type HelpMe() as this =
inherit Class1()
do
printfn "%A" this.ProtectedEvent
member x.HookEvents() =
printfn "%A" x.ProtectedEvent
member private x.HookEvents2() =
printfn "%A" x.ProtectedEvent
override x.OverrideMe() =
printfn "%A" x.ProtectedEvent
In this example I have attempted to call printfn on it, as there are multiple ways to hook up events in F# and I wanted to be clear that is simply the referencing of the event at all that causes the problem.
In each of the cases above the compiler complains with the following error
A protected member is called or 'base' is being used. This is only
allowed in the direct implementation of members since they could
escape their object scope.
I understand this error, what causes it and its purpose. Usually, the work around is to wrap the call in a private member, which works fine with methods - but that does not seem to work with events. No matter what I try, it seems to be impossible to use protected events in F# unless I resort to doing something with reflection, or make some changes to the base class (which in my case is not possible).
Note that I have also tried all possible combinations of using base, this and x.
Am I doing something wrong ?
I suspect that there is something about the code that the compiler generates behind the scene when you treat the event as a first-class value that later confuses it (i.e. some hidden lambda function that makes the compiler think it cannot access the protected member). I'd say that this is a bug.
As far as I can see, you can workaround it by using add_ProtectedEvent and remove_ProtectedEvent members directly (they do not show in the auto-completion, but they are there and are accessible - they are protected, but calling them is a direct method call, which is fine):
type HelpMe() =
inherit Class1()
member x.HookEvents() =
let eh = System.EventHandler(fun _ _ -> printfn "yay")
x.add_ProtectedEvent(eh)
override x.OverrideMe() =
printfn "hello"
This compiled fine for me. It is a shame that you cannot use the protected event as a first-class value, but this at least lets you use it...

Why is F# inferring my function implements IComparable?

I'm a hobbyist programmer (cook by trade) that's currently trying to teach myself F# and functional programming in general.
Anyway, I was fooling around with DeflateStream and wrote the following two functions:
let Compress compressMe =
let ds = new DeflateStream(File.Create("compressed.txt"), CompressionMode.Compress)
File.OpenRead(compressMe).CopyTo(ds)
ds.Close()
let Decompress =
let ds = new DeflateStream(File.OpenRead("compressed.txt"), CompressionMode.Decompress)
ds.CopyTo(File.Create("decompressed.txt"))
ds.Close()
In the body of the main function they are called one right after the other like this:
Compress args.[0]
Decompress
However, if compressed.txt doesn't exist when the program is run Decompress throws a FileNotFoundException which is surprising because the only thing that could throw this is the call to File.OpenRead("compress.txt"). After about an hour I figured out that Decompress was implementing IComparable and was being executed before the call to it in the main function. I found that by changing its definition to let Decompress () = [...] it no longer implemented IComparable and my code executed as it was intended to. Can anyone tell me why F# was infering IComparable and why such and inference would cause the function to execute before the main function marked with [<EntryPoint>]? Also, please forgive the imperitive style of my code, I'm incredibly new at this.
Thanks in adavance.
I'm not entirely sure about the IComparable bit, but the issue you have is that without the parentheses, the compiler is treating Decompress as a value not a function. This would be similar to if you had written.
let compressedName = "compressed.txt"
in that case, compressedName is now a value. Adding the parentheses tells the compiler that this is a function whose code must be called each time the function is rather than a value initialized once (before the entry point) by the code you wrote.
When you write something like
let value =
//some long calculation
[<Entrypoint>]
let main args = ...
The compiler executes the long calculation before main. This is because you probably use the value later in your code. To suppress this, as you found, you need to use let value() = ....
I am not sure where Icomparable is coming from, but this is the key to what is happening.
Note, if you write
let a = ...
let b = ...
The compiler will gurantee a is calculated before b executes.
As others have pointed out, the absence of parentheses in the declaration is significant.
let Decompres = ...
declares a variable of type unit. This type is used to represent "data" (even if this data doesn't encode much information), and it implements IComparable like any other data-oriented type.
let Decompress() = ...
declares a function, and functions in F# are not comparable, probably because there is no universally accepted notion of equality on functions.
I can't see that the "IComparable-ness" of Decompress had anything to do with the exception you got.

Testing IO in F#

Given i have the IO function:
// this can either be IO or some other side effect
//that makes the function less pure
printf "HI"
I want to test that IO was called correctly. An imperative solution for testing that IO was called correctly would be to wrap the IO statement in an object, mock the object, pass the object in using dependency injection, and verify the correct method was called with the correct parameters. I wonder if instead of using dependency injection to test F#, a better way would be checking the output of the function (by asserting that the correct value or function is returned) and stub out the IO call; therefore making the function pure again by eliminating the side effect of an IO call.
I am considering wrapping all IO in a special module like so.
let MyPrint print statement = print statement ; statement
so that i can stub out the IO function and assert in my tests that the correct operation occurred like so:
code under test:
let PrintHi = fun(print) -> MyPrint print "HI"
let DoNothing = fun(print) -> ()
let DoIf conditional =
if conditional then PrintHi
else DoNothing
FsUnit:
[<Test>] member test.
let printStub value = ()
``Test Hi Is Printed When TRUE`` ()=
let testedFunc = DoIf true
testedFunc(printStub) |> should equal PrintHi(printStub)
Is this a good way to test IO side effects? Is there a better way? Please keep in mind that my goal is to test any IO, not just a print statement.
Generally speaking, you'll want to separate pure code from impure (side-effecting) code; and keep code as pure as possible.
I recommend reading these articles about it, they're written for other functional languages but the code they use is simple and the concepts are well explained and can be easily applied in F# (and many other languages for that matter):
Introduction to QuickCheck (Haskell wiki)
How to write a functional program with IO, mutation, and other effects
You could write a wrapper function which temporarily redirects stdout during the call to a function and returns the written values along with the function result:
let testPrintf f arg =
let oldOut = System.Console.Out
use out = new System.IO.StringWriter()
System.Console.SetOut(out)
let res = f arg
System.Console.SetOut(oldOut)
(res, out.GetStringBuilder().ToString())
I guess you don't really want to check if printf works as expected (to you?) - I think you want to know if there is some more functional way than DI to get testable results.
The answer is twofold:
First: F# is a mixed languague with a big OOP part - so yes I would do your standard DI pattern with interfaces and all that.
Second: instead of using this pattern you can allways use higher-order functions to pass in functions that does for example the IO - in your case something like
let myFunctionUsingIO (printer : string -> unit) (whateverparamsYouNeed) = ...
and then test this by passing a printer that Asserts whatever your requirements are - but in the end thats the same as having a interface with only one (unnamed) method - so the difference is very small.
PS: if you only interessted in the return value - just do normal unit-testing - if you write your functions pure there is no need to test anything different, but then your example was ... well poor, because printf is the opposite of pure...

Why can't a function with byref be converted directly to delegate?

Under normal circumstances, F# functions can be converted to delegates by calling new DelegateType and passing in the function as an argument. But when the delegate contains byref parameter, this is not possible directly. For example the code:
type ActionByRef<'a> = delegate of 'a byref -> unit
let f (x:double byref) =
x <- 6.0
let x = ref 42.0
let d = new ActionByRef<_>(f)
won't compile, giving the following error:
This function value is being used to construct a delegate type whose signature includes a byref argument. You must use an explicit lambda expression taking 1 arguments.
Following the error, modifying the code to use
let d = new ActionByRef<_>(fun x -> f(&x))
works. But my question is: why is this necessary? Why won't F# allow the conversion from named function to this delegate, but conversion from lambda is fine?
I came upon this behavior when researching another question. I realize byref is meant only for compatibility with other .Net languages.
I think the problem is that byref<'T> is not an actual type in F# - it looks like a type (to make the language simpler), but it gets compiled to a parameter marked with the out flag. This means that byref<'T> can be only used in a place where the compiler can actually use the out flag.
The problem with function values is that you can construct function e.g. by partial application:
let foo (n:int) (b:byref<int>) =
b <- n
When you pass foo as an argument to a delegate constructor, it is a specific case of partial application (with no arguments), but partial application actually needs to construct a new method and then give that to the delegate:
type IntRefAction = delegate of byref<int> -> unit
let ac = IntRefAction(foo 5)
The compiler could be clever and generate new method with byref parameter (or out flag) and then pass that by reference to the actual function, but in general, there will be other compiler-generated method when you don't use the fun ... -> ... syntax. Handling this would add complexity and I think that's a relatively rare case, so the F# compiler doesn't do that and asks you to be more explicit...

Resources