How do I cast a "string" into a "option<string>" - f#

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

Related

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...

Type test pattern matching for DUs

With DU (Discriminated Union types), how do I perform a type test pattern matching ?
I have this following running code :
type IU =
|Int of int
|Unit of Unit
let x = IU.Int(3)
let y = IU.Unit(())
let z = [3.14]
let showI (v) =
match box v with
| :? IU ->
match v with
| Int(_) -> "an IU int"
|_ -> "not a IU.int"
|_ -> "not a IU.int"
But I am not happy with the inner match in the showI function. I would have preferred something like :
let showI (v) =
match box v with
| :? IU.Int -> "an int"
|_ -> "not a IU.int"
which doesn't compile (error : the type Int is not defined).
Is there an obvious syntax I missed ? Thanks.
Note : showI function accepts a variable with an unknowned type ; that is the reason for the smelly box v.
As others have pointed out, I don't think there's any built-in language feature that lets you do this. However, you could define an active pattern that performs the type test:
let (|IsIU|_|) (candidate : obj) =
match candidate with
| :? IU as iu -> Some iu
| _ -> None
This active pattern has the type obj -> IU option.
You can compose your own custom active pattern with standard patterns, like this:
let showI = function
| IsIU (IU.Int i) -> "an IU int"
| _ -> "not a IU.int"
In this example, the custom IsIU active pattern has been composed with a standard identifier pattern that matches on the IU.Int case.
Here's a sample FSI session showing usage with the x, y, and z values given in the OP:
> showI x;;
val it : string = "an IU int"
> showI y;;
val it : string = "not a IU.int"
> showI z;;
val it : string = "not a IU.int"
Staying within the context of your question I believe what you are missing is that IU.Int is not a type, but a case Int of discriminated union type IU. When you write
let x = IU.Int(3)
the type of value x is IU, not IU.Int. That's why compiler barks upon your attempt to match obj to UI.Int with :? pattern.
In a broader context, it seems you try approaching F# a-la dynamic language of Javascript kind, which it is not. Exaggerating a bit, you seemingly try using functions operating upon arguments of only one type obj and hence spending substantial run-time effort on dynamic discovery of specific argument types with wide opportunities for making mistakes on the way.
Such approach misses the whole point of F# idiomatic DU use case, which is disassembling of a value that is known to be statically typed as IU by pattern match machinery to specific union case (IU.Int or IU.Unit):
let showI (v : IU) = // explicit argument type is added to illuminate the point
match v with
| IU.Int(x) -> sprintf "a IU.Int(%i) value" x
| _ -> "a IU.Unit"
So, if you by mistake try calling showI with argument that is not of type IU, compiler will catch the erroneous use of your function with argument of wrong type right away and simply will not build the executable form of your code until the mistake is corrected.
EDIT: Idiomatic use aside you may get away with a single match, indeed, with the help of when guard, like in a snippet below, although this is a nasty hack:
open Microsoft.FSharp.Reflection
let showI (v) =
match box v with
| :? IU as x when (fst(FSharpValue.GetUnionFields(x, typeof<IU>))).Name.Equals("Int")
-> "an IU.Int"
| _ -> "not an IU.Int"

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 to downcast from obj to option<obj>?

I have a function that takes a parameter of type object and needs to downcast it to an option<obj>.
member s.Bind(x : obj, rest) =
let x = x :?> Option<obj>
If I pass (for example) an Option<string> as x, the last line throws the exception: Unable to cast object of type 'Microsoft.FSharp.Core.FSharpOption'1[System.String]' to type 'Microsoft.FSharp.Core.FSharpOption'1[System.Object]'.
Or, if I try a type test:
member s.Bind(x : obj, rest) =
match x with
| :? option<obj> as x1 -> ... // Do stuff with x1
| _ -> failwith "Invalid type"
then x never matches option<obj>.
In order to make this work, I currently have to specify the type the option contains (e.g. if the function is passed an option<string>, and I downcast the parameter to that rather than option<obj>, the function works.
Is there a way I can downcast the parameter to option<obj> without specifying what type the option contains? I've tried option<_>, option<#obj>, and option<'a> with the same results.
By way of background, the parameter needs to be of type obj because I'm writing an interface for a monad, so Bind needs to bind values of different types depending on the monad that implements the interface. This particular monad is a continuation monad, so it just wants to make sure the parameter is Some(x) and not None, then pass x on to rest. (The reason I need the interface is because I'm writing a monad transformer and I need a way to tell it that its parameter monads implement bind and return.)
Update: I managed to get around this by upcasting the contents of the option before it becomes a parameter to this function, but I'm still curious to know if I can type-test or cast an object (or generic parameter) to an option without worrying about what type the option contains (assuming of course the cast is valid, i.e. the object really is an option).
There isn't any nice way to solve this problem currently.
The issue is that you'd need to introduce a new generic type parameter in the pattern matching (when matching against option<'a>), but F# only allows you to define generic type parameters in function declarations. So, your only solution is to use some Reflection tricks. For example, you can define an active pattern that hides this:
let (|SomeObj|_|) =
let ty = typedefof<option<_>>
fun (a:obj) ->
let aty = a.GetType()
let v = aty.GetProperty("Value")
if aty.IsGenericType && aty.GetGenericTypeDefinition() = ty then
if a = null then None
else Some(v.GetValue(a, [| |]))
else None
This will give you None or Some containing obj for any option type:
let bind (x : obj) rest =
match x with
| SomeObj(x1) -> rest x1
| _ -> failwith "Invalid type"
bind(Some 1) (fun n -> 10 * (n :?> int))
I am not certain why you need to get your input as obj, but if your input is an Option<_>, then it is easy:
member t.Bind (x : 'a option, rest : obj option -> 'b) =
let x = // val x : obj option
x
|> Option.bind (box >> Some)
rest x
To answer your last question: you can use a slight variation of Tomas' code if you need a general-purpose way to check for options without boxing values beforehand:
let (|Option|_|) value =
if obj.ReferenceEquals(value, null) then None
else
let typ = value.GetType()
if typ.IsGenericType && typ.GetGenericTypeDefinition() = typedefof<option<_>> then
let opt : option<_> = (box >> unbox) value
Some opt.Value
else None
//val ( |Option|_| ) : 'a -> 'b option
let getValue = function
| Option x -> x
| _ -> failwith "Not an option"
let a1 : int = getValue (Some 42)
let a2 : string = getValue (Some "foo")
let a3 : string = getValue (Some 42) //InvalidCastException
let a4 : int = getValue 42 //Failure("Not an option")

F#: Nullable<T> Support

What is the right way to use Nullable in F#?
Currently I'm using this, but it seems awefully messy.
let test (left : Nullable<int>) = if left.HasValue then left.Value else 0
Console.WriteLine(test (new System.Nullable<int>()))
Console.WriteLine(test (new Nullable<int>(100)))
let x = 100
Console.WriteLine(test (new Nullable<int>(x)))
I'm afraid there's no syntactical sugar for nullable types in F# (unlike in C# where you simply append a ? to the type). So yeah, the code you show there does look terribly verbose, but it's the only way to use the System.Nullable<T> type in F#.
However, I suspect what you really want to be using are option types. There's a few decent examples on the MSDN page:
let keepIfPositive (a : int) = if a > 0 then Some(a) else None
and
open System.IO
let openFile filename =
try
let file = File.Open (filename, FileMode.Create)
Some(file)
with
| exc -> eprintf "An exception occurred with message %s" exc.Message; None
Clearly a lot nicer to use!
Options essentially fulfill the role of nullable types in F#, and I should think you really want to be using them rather than nullable types (unless you're doing interop with C#). The difference in implementation is that option types are formed by a discriminated union of Some(x) and None, whereas Nullable<T> is a normal class in the BCL, with a bit of syntactical sugar in C#.
You can let F# infer most of the types there:
let test (left : _ Nullable) = if left.HasValue then left.Value else 0
Console.WriteLine(test (Nullable()))
Console.WriteLine(test (Nullable(100)))
let x = 100
Console.WriteLine(test (Nullable(x)))
You can also use an active pattern to apply pattern matching on nullable types:
let (|Null|Value|) (x: _ Nullable) =
if x.HasValue then Value x.Value else Null
let test = // this does exactly the same as the 'test' function above
function
| Value v -> v
| _ -> 0
I blogged some time ago about nullable types in F# [/shameless_plug]

Resources