I'm new to F# and I'm trying to implement a little calculator with these interfaces...
But I'm struggling with the derive part as soon as i get to f_add.
Would be nice if someone could help me out. :)
type IFunction =
interface
abstract member ToString: Unit -> String
abstract member Apply: Nat -> Nat
abstract member Derive: Unit -> IFunction
end
Since f_add is defined in curried form (typical for F# functions), and not tupled, you need to pass the arguments with spaces, not as a tuple:
// HERE . Using comma makes that a tuple
// member self.Derive () = f_add(f.Derive (), g.Derive ()) //wrong
Instead, pass as an F# style function:
member self.Derive () = f_add (f.Derive ()) (g.Derive ())
The same issue exists in the other implementations.
Related
when I try to create a curried constructor, like
class MyClass(a: Int, b: Int)(c: String) {
// Some Implementation
}
why does partial application like
val partialConstructor = new MyClass(x, y)
result in the error message
missing argument list for constructor MyClass in class MyClass
You confuse curried functions with functions of multiple argument lists. Take a look at this answer why there are function with multiple argument lists.
For your example you should explicitly say that you want a curried function
val partialConstructor = new MyClass(x, y)(_)
Background: I am trying to expand my existing logging framework, which is currently a wrapper of static non-thread-safe methods over printfn and friends. My design goals are: having a generic interface ILog and concrete classes like Dbg, Log, Trace. I cannot use modules and functions, unfortunately, because I like to leverage the ConditionalAttribute on the methods.
I have a working approach that looks something like this:
type ILog<'T, 'U, 'V> =
abstract member log: 'T -> unit
abstract member log: 'U * 'V -> unit
type Dbg<'T, 'U, 'V when 'T :> Printf.StringFormat<string> and 'U :> Printf.StringFormat<'V -> string>>() =
static member inline _do_other_stuff() = "other stuff"
static member inline private _helper() =
printfn "%s %s" (Dbg<_,_,_>._do_other_stuff())
interface ILog<'T, 'U, 'V> with
[<Conditional("DEBUG")>] // removed from call site
member this.log(msg) = sprintf msg |> Dbg<_,_,_>._helper()
[<Conditional("DEBUG")>] // removed from call site
member this.log(fmt, a) = sprintf fmt a |> Dbg<_,_,_>._helper()
module TestMe =
let test() =
let dbg = new Dbg<_,_,_>() :> ILog<_,_,_>
dbg.log("test%i", 2)
Here, the compiler and syntax checker and coloring detects properly the dbg.log("test%i", 2) line, which is exactly what I want. It will also properly raise an error if I were to write "test%s" instead.
Now, if I take the above approach and expand it to create more overloads of the ILog.log method, this gets pretty hairy pretty quickly because of all the type annotations and the required use of syntax like Dbg<_,_,_>. Some of it can be hidden away, but still I figured there must be a better way.
One approach I tried, which seemed very FSharpish is:
type ILog =
abstract member log: _ -> unit
abstract member log: _ * _ -> unit
This compiles the interface and infers the type to be 'a0 and 'a0 -> 'a1 respectively (which seems wrong, why is the second log member getting the same 'a0?). But, I can't find any way of implementing such overly generic interface:
type Dbg() =
interface ILog with
member this.log v = v + 1 |> ignore // it won't infer int here
It raises:
The declared type parameter '?' cannot be used here, since the type parameter cannot be resolved at compile time.
Does F# 4.0 have a way of declaring interfaces in a more generic way, or am I stuck to having to declare them specifically (while this works, it is tedious).
Looking at the following Scala in Depth code, what does handle -> callback mean?
trait Observable {
type Handle
def observe(callback: this.type => Unit): Handle = {
val handle = createHandle(callback)
callbacks += (handle -> callback)
handle
[code omitted]
}
-> ultimately comes from scala.ArrowAssoc. scala.Predef also defines:
#inline implicit def any2ArrowAssoc[A](x: A): ArrowAssoc[A] = new ArrowAssoc(x)
which causes an implicit conversion of Any to an ArrowAssoc. This has the effect of adding ArrowAssoc's -> method to all objects (because all objects inherit from Any).
As to what -> does, it merely returns a Tuple2 of the two parameters. Or to put it another way, (handle -> callback) is more or less identical to (handle, callback).
Although you've deleted the definition, callbacks is probably a mutable.Map object. += adds (or updates) an entry in said map associating handle to callback. So basically, this appears to be adding the newly-created handle and the callback to a map of callbacks.
Handle is an "abstract type". It must be defined in a concrete subclass.
callback is a function that takes a (this.type) and returns nothing (Unit).
The -> syntax is just alternate syntax for a tuple:
(3 -> "abcd") is the same as (3, "abcd")
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())
Imagine the following interface in C#:
interface IFoo {
void Bar();
}
How can I implement this in F#? All the examples I've found during 30 minutes of searching online show only examples that have return types which I suppose is more common in a functional style, but something I can't avoid in this instance.
Here's what I have so far:
type Bar() =
interface IFoo with
member this.Bar() =
void
Fails with _FS0010:
Unexpected keyword 'void' in expression_.
The equivalent is unit which is syntactically defined as ().
type Bar() =
interface IFoo with
member this.Bar () = ()
For general info on F# types, see
The basic syntax of F# - types
From that page:
The unit type has only one value, written "()". It is a little bit like "void", in the sense that if you have a function that you only call for side-effects (e.g. printf), such a function will have a return type of "unit". Every function takes an argument and returns a result, so you use "unit" to signify that the argument/result is uninteresting/meaningless.
The return type needs to be (), so something like member this.Bar = () should do the trick
The equivalent in F# is:
type IFoo =
abstract member Bar: unit -> unit