I have gone through the documentation and source code for System.String. I can see that the default indexer is defined with this[int index] and that the alias "Chars" is used. I want to extend it by writing the below code.
type System.String with
member self.Chars (boolean:bool) = if boolean then self.[0] else self.[1]
printfn "%c" ("abc".[false])
printfn "%c" ("abc".Chars(false))
The reason why is because I have seen other articles and code snippets pointing to the idea that I would have this ability. I am now trying to test it out. I also noticed that System.String is defined as Sealed.
[<Sealed>]
I have been doing many searches and looking at sites like fssnip.net and Tomas P's articles and here on Stackoverflow. What am I missing?
The reason why this is not working is because Chars is an alias to a property and not a method itself. Extension methods seem to not be possible on properties.
Even though it is a get with a parameter, there would had to of been a generic version created and that would likely need to point to a method that I could create my constrained version from. #Ringil led me in the right direction. Thank you. Good day.
Related
(Really Really confused).
I have a class, Visit, downloaded from a WCF service. It has a member defined as:
public System.Nullable<System.DateTime> service_time
In F# Code, how is null written to this member? Or how to convert this C# class to F# record with Option?
Thanks in advance.
If the member is writable, you can use <- to modify it, like this:
myObject.service_time <- Nullable DateTime.Now
To create a Nullable value without a value inside it, use its parameterless constructor:
myObject.service_time <- Nullable()
Judging by your questions, it looks like you're only just starting out and don't even have a good baseline from which to explore. If this is the case, I would recommend doing some reading first, and maybe doing some toy exercises, before trying to actually implement things. One source that I found particularly useful is fsharpforfunandprofit.com. Check it out.
I just started to study F# and accidentally wrote this binding
let List = 1
Now when I try to obtain List methods such as 'filter' I get this error
error FS0039: The field, constructor or member 'filter' is not defined.
Of course using method with full type name like Microsoft.FSharp.Collections.List.filter is still working.
I'm wondering why it is possible to use type name as identifier in F# and how I can set back name List to type List from Microsoft.FSharp.Collections.
When I tried to reassign like this
type List = Microsoft.FSharp.Collections.List<'T>
I get
Error FS0039: The type parameter 'T is not defined.
Thank you!
In F# you can redefine almost everything and shadow existing definitions. This applies to both types (well actually types have a different behavior regarding shadowing, they shadow their values as you open the namespaces) and values but not interchangeably since values and type (and also modules) can somehow coexist at the same time in the scope. The compiler will do his best to find out which one is.
You are not forced to, but it's a common good practice in F# not to use let bindings in uppercase.
Regarding your second question, you are using a type parameter in the right side which doesn't exist in the left side of the assignment, it should be:
type List<'T> = Microsoft.FSharp.Collections.List<'T>
But notice that filter doesn't belong to the type. It's rather defined in the List module.
You should just rename your let binding from List to something sensible - as Gustavo mentioned, your definition is shadowing the core List module from F# and there is no way to use List to refer both to your integer and to the module. Shadowing core functions will make your code pretty confusing. It's also a good idea to use camelCase for let bindings, but that's a matter of taste.
If you insist on shadowing List, then you won't be able to call List.filter using List.filter. If you wanted something shorter, you could define module alias:
module FsList = Microsoft.FSharp.Collections.List
Note that your attempt to do something similar with List<'T> does not do the same thing, because functions such as filter are in a module named List rather than being static members of the type. With this, you can call filter using FsList.filter.
I am getting the following error when reading date values out of postgresql using npgsql:
This expression was expected to have type
DateTime
but here has type
NpgsqlTypes.NpgsqlDate
Now the npgsql docs refer to an explicit operator being defined:
[C#]
public static explicit operator DateTime(
NpgsqlDate date
);
but I can't figure out how to access this from F#.
There are several kludgy, longhand ways of achieving what I need, but I am disappointed and frustrated that I was unable to find a way of accessing the inbuilt cast.
I tried the old Convert.ToDateTime(...), but even that doesn't work.
Anybody got a clue? Thx.
The explicit conversion operator can be accessed by calling the op_Explicit (I had the casing wrong in the earlier comment; I had not tried it myself then) function on the type:
let date = NpgsqlDate.op_Explicit npgsqlDate
I have also found various places (like in Yan Cui's blog here) that define an F# operator like !> for (all!) explicit conversions for convenience, so you can just say
let date = !> npgsqlDate
I think that is a pretty neat way.
I've been programming in F# for some years and there's an "issue" that's been bothering me for some time and I have not been able to solve. It is not a bug, I think it is a design decision, but anyway, the problem is this: is there a way to delay (maybe that's not the correct word for this) the implementation of interfaces?, that is, not implementing them in the initial definition, but later, maybe in the same file after I have implemented a module for the type. I'll explain with a simplified example:
Suppose I have the following data structure:
type 'T MyCollection =
(*type definition*)
interface IEnumerable<'T> with
member this.GetEnumerator () =
(* I don't want to implement it here
because I still don't have the module
with a toSeq function *)
If I implemented the method right there, I would have to also implement all the functions as methods of the type and then the module would be just a "proxy" for calling the methods. This way I'm creating a OO-first data structure and then creating a module (overloaded with type annotations) to allow for a functional-first usage. I would prefer to write a functional-first data structure (cleaner since the type inference can work better) and then create a OO wrapper to allow a better intellisense support for languages like C#. That approach complies with what the design guidelines for F# tells us, but the interfaces can't be implemented anywhere but in the initial definition of the type. That restriction forces me to write the whole data structure with members.
I've been looking for examples and I've found that the list implementation in FSharp.Core list does exactly what I want, but I can't do that, the compiler won't let me.
I'm almost sure that this is a design decision, maybe to avoid encouraging bad practices, I don't know, but I don't consider my wish to be a bad practice. Also I'm well aware of the linear nature of the fsharp compiler.
Please if any of you know how to do what I want, I'll be glad if you tell me. Also, if any of you know why I should not follow this approach I'll be glad to know too. There must be a reason why this is not a problem for anyone else.
Thanks in advance.
I completely agree that this is unfortunate problem. The trick that is used in the source code of 'a list in the F# Core library is to define the implementation of the interface in a type augmentation. The compiler does not complain when you add members to a type in this way, but it says that adding implementation of an interface in this way is deprecated. However, it does not prevent you from doing this. The following compiles fine for me:
open System.Collections
open System.Collections.Generic
type MyCollection<'T> =
{ Data : 'T list }
interface IEnumerable<'T>
interface IEnumerable
let getEnumerator { Data = d } =
(d :> seq<_>).GetEnumerator()
type MyCollection<'T> with
interface IEnumerable<'T> with
member this.GetEnumerator() = getEnumerator this
interface IEnumerable with
member this.GetEnumerator() = (getEnumerator this) :> _
The fact that this is deprecated is a bit unfortunate. I quite like this style and I use it when it makes sense. You can start a discussion about this on F# user voice and perhaps it could be turned back into a normal accepted feature :-)
I am getting the following error in my mvc application when I am doing the paging functionality
CS1061: 'System.Collections.Generic.IEnumerable' does not contain a definition for 'HasPreviousPage' and no extension method 'HasPreviousPage' accepting a first argument of type 'System.Collections.Generic.IEnumerable' could be found (are you missing a using directive or an assembly reference?)
please tell me what to do and what is that Model.
This reminds me of the PaginatedList<T> class found in the Conery et al MVC 1.0 Wrox book... (And probably also found in the NerdDinner app.) I actually have this book right here next to me and have this section tabbed. And sure enough they have a property called HasPreviousPage, which leads me to guess this is what you are working with? It is in Chapter 1, which is a free download. (Google for it.) I highly recommend taking a look at this chapter, or at least this section, as there are many other helpful suggestions and tips to be found!
Best of luck!
I think that you may be missing a namespace import.
Is HasPreviousPage a method or a property? If it is a helpermethod on the type of list you are returning then you need to import that namespace in your aspx file (or in the web.config to reflect on all pages)
You need to change the controller to use Paging, check out http://blogs.embarcadero.com/johnk/2009/04/02/38871 for more info
EDIT: To clarify, so somewhere in the Controller, you're gonna see something to the effect of "return View(someModelObject)" - you need to use PaginationHelper.AsPagination here to turn someModelObject into a pageable object
There are a few possibilities here:
First off, Model is your object, or class. HasPreviousPage is a method or function in Model.
Here are some possibilities:
Model is not defined because the file is not included in the page
HasPreviousPage does not exist as a method
HasPreviousPage is actually a property and needs more information to extract data (as tster is saying)
The signature for HasPreviousPage is incorrect. You are sending too much, or not enough data.
My guess is it's either a boolean property, or a method that returns a boolean. Either way the compiler has no idea what to do with it, so you need to track it down. Try doing a find in your solution for "HasPreviousPage". See if it's been referenced anywhere, or where it is located.
Ctrl + F
Find What:
HasPreviousPage
Look In:
Entire Solution