Does F# support templates or Generics? - f#

I want to implement a heap data structure and want to apply the code to any type that supports comparison, i.e. < = > <= >= operations.
How to do this in F# as it is statically typed.

It does, but you have to annotate as follows:
type Thing<'a when 'a:comparison> =
| Pair of ('a*'a)
with
member m.InOrder() =
match m with
| Pair (a,b) when a<=b -> true
| _ -> false
member m.Equal() =
match m with
| Pair (a,b) when a=b -> true
| _ -> false
Pair(1,2).InOrder() //true
Pair(3,2).InOrder() //false
Pair(42,42).Equal() //true
Try replacing Thing<'a when 'a:comparison> by Thing<'a when 'a:equality> to watch the InOrder() method fail, while Equal() still works. Replace Thing<'a when 'a:comparison> by Thing<'a> and both methods won't work.

For more on the specific cases of equality and comparison constraints, see
http://lorgonblog.spaces.live.com/blog/cns!701679AD17B6D310!1621.entry
and
http://blogs.msdn.com/dsyme/archive/2009/11/08/equality-and-comparison-constraints-in-f-1-9-7.aspx

Yes it does support generics - look at this as an example.

Related

Overloading global && operator in Haskell fails to compile

I've got a hs file, trying to overload && operator
(&&)::Bool->Bool->Bool
True && x = x
False && _ = False
and' :: (Bool)->Bool
and' xs=foldr (&&) True xs
When imported in Prelude, there's error:
Ambiguous occurrence ‘&&’
It could refer to either ‘Main.&&’, defined at D:\baby.hs:2:6
or ‘Prelude.&&’,
imported from ‘Prelude’ at D:\baby.hs:1:1
(and originally defined in ‘GHC.Classes’)
So I changed the last line to be
and' xs=foldr (Main.&&) True xs
Now it prints new error message:
Couldn't match expected type ‘t0 Bool’ with actual type ‘Bool’
In the third argument of ‘foldr’, namely ‘xs’
In the expression: foldr (Main.&&) True xs
How can I resolve this issue? Thanks.
As #zakyggaps said in his comment, (Bool) is the same as Bool. You clearly mean [Bool]. Also, you aren't really "overloading" this function so much as defining a similarly named one in a different module. "Shadowing" at best, but not even that really.
There is no overloading in Haskell. Identifiers can be shared using typeclasses, but && is not a member of a typeclass and thus cannot be shared. When you define your own && operator, it conflicts with the one automatically imported in the Prelude. To use your && without qualification, you must hide Prelude.&& as follows:
import Prelude hiding ((&&))
(&&) :: Bool -> Bool -> Bool
True && b = b
False && _ = False
The second error is a mistake or typo in the type of and', which should be and' :: [Bool] -> Bool rather than and' :: (Bool) -> Bool.

F# out parameters and value types

The following f# function works great if I pass references to objects, but will not accept structs, or primitives:
let TryGetFromSession (entryType:EntryType, key, [<Out>] outValue: 'T byref) =
match HttpContext.Current.Session.[entryType.ToString + key] with
| null -> outValue <- null; false
| result -> outValue <- result :?> 'T; true
If I try to call this from C# with:
bool result = false;
TryGetFromSession(TheOneCache.EntryType.SQL,key,out result)
I get The Type bool must be a reference type in order to use it as a parameter Is there a way to have the F# function handle both?
The problem is that the null value in outValue <- null restricts the type 'T to be a reference type. If it has null as a valid value, it cannot be a value type!
You can fix that by using Unchecked.defaultOf<'T> instead. This is the same as default(T) in C# and it returns either null (for reference types) or the empty/zero value for value types.
let TryGetFromSession (entryType:EntryType, key, [<Out>] outValue: 'T byref) =
match HttpContext.Current.Session.[entryType.ToString() + key] with
| null -> outValue <- Unchecked.defaultof<'T>; false
| result -> outValue <- result :?> 'T; true
I still think this is not "pretty"/idomatic F# code and would probably do some more seremonial with the following:
let myCast<'T> o =
match box o with
| :? 'T as r -> Some(r)
| _ -> None
let GetFromSession<'T> entryType key =
match HttpContext.Current.Session.[entryType.ToString + key] with
| null -> None
| r -> myCast<'T> r
This is also kind of "safer" and will (should?) not throw any exception, and it removes the null-stuff in F#. In C# it will return and work ok too, but None are returned as null, and if some result, well yeah it will be Some ;-)
Mind that the above code are not tested, not run in any setting or even compiled, so regard it as pseudo code. It might even have other issues...
Check also:
https://msdn.microsoft.com/en-us/library/dd233220.aspx
and
http://fsharpforfunandprofit.com/posts/match-expression/
On the last link especially: Matching on subtypes
On a side note, I do not like the missing checking of entire hierachy from HttpContext to Session are non-null, but that might just be me...
Update for some C# code using None/Some
var x = GetFromSession<MyTypeInSession>(entryType, key)?.Value??defaultValue;
There is absolutely no need for going full arabic, reading from right to left, and from down and up with a pyramidal scheme of ifs and buts and no candy or nuts, for null-checking et al ad nauseam.
And again code is to be regarded as pseudo code...

How to do pattern matching in Rx. Where and Select in a single operator?

Suppose I have this type:
type T = int option
and an observable of that type:
let o : IObservable<T> = // create the observable
I'm looking for a better way to express this:
o.Where(function | None -> false | Some t -> true)
.Select(function | Some t -> t)
An observable that only propagates the Some case.
There are several things that I don't like.
I'm using 2 operators
I'm pattern matching twice
The second pattern matching isn't exhaustive (makes visual studio show a warning and feels odd)
Too much code. The pattern repeats every time I need pattern matching.
Can't you use Observable.choose ? something like this :
let o1 : IObservable<int option> = // ...
let o2 = Observable.choose id o1
If you have a type that is not an option, say:
type TwoSubcases<'a,'b> = | Case1 of 'a | Case2 of 'b
and a partial active pattern:
let (|SecondCase|_|) = function
| Case1 _ -> None
| Case2 b -> Some b
then you can do:
let o1 : IObservable<TwoSubcases<int, float>> = // ...
let o2 : IObservable<float> = Observable.choose (|SecondCase|_|) o1
Thanks to #Lee I came up with a nice solution.
o.SelectMany(function | None -> Observable.Empty() | Some t -> Observable.Return t)
This works for any union type, not only Option.

Pattern combining type test and literal

The active pattern in this question fails to compile after upgrading to VS 2012 RTM. It provides a way to do a type test and match a literal within a single pattern. For example:
let (|Value|_|) value =
match box value with
| :? 'T as x -> Some x
| _ -> None
let getValue (name: string) (r: IDataReader) =
match r.[name] with
| null | :? DBNull | Value "" -> Unchecked.defaultof<_>
| v -> unbox v
Can this be done without the active pattern? I realize a when guard could be used (:? string as s when s = "") but it can't be combined with other patterns.
kvb's variation (which doesn't do quite the same thing since it assumes the type test succeeds) can be modified to produce a similar pattern:
let (|Value|_|) x value =
match box value with
| :? 'T as y when x = y -> Some()
| _ -> None
However, there is a subtle performance difference. The original active pattern translates to:
public static FSharpOption<T> |Value|_|<a, T>(a value)
{
object obj = value;
if (!LanguagePrimitives.IntrinsicFunctions.TypeTestGeneric<T>(obj))
{
return null;
}
return FSharpOption<T>.Some((T)((object)obj));
}
that is, it does a type test and cast. It's usage (match x with Value "" -> ...) translates to:
FSharpOption<string> fSharpOption = MyModule.|Value|_|<object, string>(obj);
if (fSharpOption != null && string.Equals(fSharpOption.Value, ""))
{
...
}
Most notably, the typed value returned from the pattern is matched using the typical compiler transformations for patterns (string.Equals for strings).
The updated pattern translates to:
public static FSharpOption<Unit> |Value|_|<T, a>(T x, a value)
{
object obj = value;
if (LanguagePrimitives.IntrinsicFunctions.TypeTestGeneric<T>(obj))
{
T y = (T)((object)obj);
T y3 = y;
if (LanguagePrimitives.HashCompare.GenericEqualityIntrinsic<T>(x, y3))
{
T y2 = (T)((object)obj);
return FSharpOption<Unit>.Some(null);
}
}
return null;
}
which uses generic equality and is less efficient than matching against a literal. The usage is a bit simpler since equality is baked into the pattern:
FSharpOption<Unit> fSharpOption = MyModule.|Value|_|<string, object>("", obj);
if (fSharpOption != null)
{
...
}
Anyway, it works. But I like the original better.
You should be able to use a parameterized active pattern:
let (|Value|_|) v x =
if unbox x = v then
Some()
else None
The usage should look exactly like what you've got now.
Edit
While I don't know if the breaking change was intentional, I believe that active patterns with generic return types unrelated to the input types should usually be avoided. When combined with type inference, they can easily mask subtle errors. Consider the following example, using your original (|Value|_|) pattern:
match [1] with
| Value [_] -> "Singleton"
| _ -> "Huh?"
It seems like this isn't something you would actually ever attempt - the name implies that Value should only be used with literals; parameterized active patterns enable exactly this scenario.

How do I cast a "string" into a "option<string>"

I have a function declared as
let GetLength (value : option<string>) =
if value.IsSome then value.Value.Length else 0
And I have the variable
let a : string = "tom"
How do I pass a to the function GetLength?
The accepted answer doesn't compile, and produces...
GetLength Some a;;
^^^^^^^^^^^^^^
error FS0003: This value is not a function and cannot be applied
F# thinks you are building a function (GetLength Some) to apply to the value a. That is because it's a functional language.
The correct form is
GetLength (Some a);;
You don't cast it. You need to use the Some constructor:
GetLength Some a
An alternative to parentheses:
GetLength <| Some a
I think it's important to address this question:
Why would anyone willing type 18
tokens over 3 lines when you can get
the exact same thing using 12 tokens
on one line?
Writing code isn't just about conciseness - it's also about readability and maintainability. Suppose you need to handle the case where a is null. With pattern matching, you could go from this:
let GetLength (value : string option) =
match value with
| Some s -> s.Length
| _ -> 0
To this:
let GetLength (value : string option) =
match value with
| Some s when s <> null -> s.Length
| _ -> 0
To an F# programmer, the meaning is clear. To fix your implementation would look something like this:
let GetLength (value : option<string>) =
if value.IsSome && value.Value <> null then value.Value.Length else 0
The result might be the same, but I don't find it particularly easy to see, at a glance, what's happening.
It's fine if pattern matching doesn't resonate with you, but the extra "cost" in the simple case is often made up for many times over as the logic evolves.
To answer the general question of casting 'a to option<'a>, if you wanted to do it safely without just applying the object to the Some constructor, there is a simple function that I would use:
let to_option = function
| null -> None
| obj -> Some obj

Resources