F# abstract member has to be public? - f#

It seems that if I declare an abstract member in a base class (so that derived class can override it), this member must be public.
However, there're cases that I don't want to expose such member as a public method. It's just for internal implementation where virtual dispatch is needed.
Since F# has no "protected", is it possible to at least make it "internal"?
Thanks!
Some context:
I'm doing some work in an existing non-small F# code base. It has already using inheritance intensively (so refactor out inheritance is not viable at the moment though it might be the right thing).
In a specific case, there are following types
type Base<'U> () =
// blah blah
type Derived1<'K, 'V when 'K equality> () =
inherit Base<'K * 'V>()
// Blah blah
type Derived2<'U> () =
inherit Base<'U>()
// Blah blah
Now for one thing I intended to do, if I do it with abstract thus can take advantage of virtual dispatching, I will add an abstract member in Base as
abstract member Member: unit -> Base<'U>
Then in Derived1 add
override x.Member () =
y = // blah blah
y :> Base<_>
And in Derived2 add
override x.Member () =
y = // blah blah
y :> Base<_>
Then I can use "Member" in other places inside Base type.
The problem is that "Member" becomes "public", but it's only for some internal implementation need. Since there's no "protected", I'd hope I can use "internal". However, it's not allowed by compiler either (any idea about the reasoning here?). How could I achieve similar thing without using "abstract" member? (and without changing the current inheritance chain, which already has tons of code ...)
Thanks very much for any suggestions!

Related

F# check if val member is uninitialized

I have an F# class that uses the following to declare, but not initialize class members:
[<DefaultValue>] val mutable myVariable : myType
How can I check in the code whether this value has been initialized? I tried:
x.myVariable = null
but that doesn't seem to work.
From your description, it is a bit hard to say what you are actually trying to achieve - using both uninitialized values and inheritance is generally not the preferred way of doing things in F# (but they are both sometimes necessary for interoperability with .NET), so if you follow this direction, you might not be getting that many advantages from using F#.
Wouldn't the following work for you instead? The idea is that we define a base class that takes the value of the private thing through a constructor:
type Base(myThing : Random) =
member x.MyThing = myThing
And an inherited class can then provide a value, but also access it using a member:
type MySubclass() =
inherit Base(new Random(0))
member x.Next() =
x.MyThing.Next()

Class definition with no parameter-list

F# accepts the following:
type Abc =
member this.A = 10
Since no parameter-list was supplied, there is no default constructor. Can a constructor be added to Abc? If not, what can be done with Abc?
I can't think of many uses for this, but two things you can do are
inherit from it, albeit derived types must not be instantiable either
extend it with static members (although this is better achieved with modules, which can also be extended)
type Abc =
member this.A = 10
[<Class>]
type Def =
inherit Abc
type Abc with
static member Foo() = ()
In C#, Code Contracts for an interface or abstract class are defined in a "contract class" which must be marked abstract and have a private constructor (i.e. it's non-instantiable). This, in my opinion, is a better way of accomplishing that. But C# doesn't support constructor-less classes.

F#: Implement an inline method (On Inteface) to avoid using a real type

I'm trying to see if inline can be applied to an implemented method so that the specific type coming in doesn't have to be spelled out. I've done this with one off (Not inherited/implemented) methods, but trying to also do using an interface.
type public IBookInteraction =
abstract inline CreateBook : 'a -> MethodResult<BasicBookModel>
type public BookInteraction(?userInteraction) =
interface IBookInteraction with
member inline x.CreateBook(bookModel) =
let userId = (^a : (member UserId : Int32 with get) (bookModel))
MethodResult<BasicBookModel>()
I'm guessing there's a way to do this, but it doesn't work with a generic operator(?) in the interface method signature.
I don't believe it's possible to have abstract inline methods. Even if you could, your code wouldn't work, because your interface definition promises that users can call it with any 'a, but your implementation places a static member constraint on 'a - in a hypothetical world where F# supported abstract inline methods, the declaration of the method on the interface would also need to include the constraint.
In any case, to see why it's not possible for F# to support abstract inline methods, consider what inline means: the code that you write to implement the method will be essentially copied and pasted into the call site. However, with an abstract method, you don't know the concrete type that is defining the implementation of the method, so there's no way to figure out at compile time what code you're supposed to be inlining!
I think the correct answer is interface implementations may not be inlined. I'm not sure why it's allowed in the interface definition.

Cyclic function/type dependency in F#

I have a question about the best way to go about the following
I Have a class B, I have a combinator on B,
let foo : B -> int.
I want the class B to have the combinator encapsulated as a method, so I add it with a type extension.
I then later on realize that foo is quite expensive and want to cache it's result with lazy evaluation
So I add a huge clutch to the system by passing the combinator as a function to the constructor and then initializing a field with foo = lazy(foo self) in the constructor.
i.e.
type foo =
class
val x : int Lazy
new (comb) as self = {x=lazy(comb self);}
end
let something (x:foo) = 1
type foo with
new() = foo(something)
this obviously feels wrong
the two options I see for fixing this are 1, make an interface and have foo inherit that interface, 2, make everything a static method and then make combinators out of those static methods(sort of the opposite of attaching them to classes...)
Neither of these are hugely appealing and I was wondering if I missed option 3
Oh, and I haven't been able to get let rec and to work quite right with this, nor would i really want to as "something" in the above statement depends on a function that depends on a function that depends on a function(3 deep).
any advice would be appreciated
I don't think there is anything wrong with your current design. The key point is that if you define the type Foo as well as the extension to the type in a same file (and the same module), then F# will combine the two parts of the definition into a single .NET type. So, the fact that it is defined in two separate parts is just an implementation detail.
If you don't want to expose the constructor that takes the combinator, you can mark it as private. Together with a few additional changes (i.e. use implicit constructor syntax), the snippet would look like this:
type Foo private (comb) as self =
let x : Lazy<int> = lazy comb self
let something (x:Foo) = 1
type Foo with
new() = Foo(something)
If you want to keep something as a separate function, then this is a fine solution. Many numeric types in the F# PowerPack follow this pattern (see for example definition of complex numbers)
I don't quite grok what you're after, but I think this may help:
type foo(comb) as self =
let x = lazy(comb self)
static member something (x:foo) = 1
new() = foo(foo.something)
A type can be recursive with its own static member, so this is a simpler way to write your code.

Unknown need for type annotation or cast

I know I must be missing something really obvious here. B.GetInstance().Call() generates the error: Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved.
I'm using v1.9.9.9.
type A() =
member x.Call() = B.GetInstance().Call()
and B() =
static member GetInstance() = new B()
member x.Call() = ()
I just discovered that this works: (B.GetInstance() :> B).Call()
Any idea why the cast is necessary?
Frequently when you've got a recursive set of methods whose types to infer, F# needs help. A more pleasant alternative would be to annotate the definition of B.GetInstance:
type A() =
member x.Call() = B.GetInstance().Call()
and B() =
static member GetInstance() : B = new B()
member x.Call() = ()
I believe that the reason you run into this problem is that F# tries to solve all inferred types on all methods in A and B simultaneously (because they are defined as mutually recursive types), and this leads to problems, but perhaps someone from the F# team will weigh in.
The quick summary is that in a recursive group (e.g. members in one type, or members of recursive types like we have here) F# reads the declarations in left-to-right top-to-bottom order, followed by the definitions in left-to-right top-to-bottom order. So in this instance when it reaches the definition of A.Call, it has not yet read the definition of B.GetInstance and therefore does not (yet!) know that the return type of GetInstance will be B.
Keith's answer nails it for this situation, you can provide a type annotation to specify the return type of GetInstance in its declaration.
See
Forcing F# type inference on generics and interfaces to stay loose
for a deep discussion of what's going on here.
Note also that in your original attempt, you don't need to "cast" (the potentially dynamic operation, using :>), instead you can just "annotate" (statically declare a type, using :) to get it to compile. But makes more sense to put the type annotation in the method declaration for GetInstance (generally, prefer addition annotations to method signatures instead of arbitrary places inside bodies).

Resources