I want to extend one of the existing "core" modules, like Core.Option
:
module Microsoft.FSharp.Core.Option
let filter predicate op =
match op with
| Some(v) -> if predicate(v) then Some(v) else None
| None -> None
(I know about bind
function, but I think filter
method for options in some case is more convenient).
But unfortunetely I can't use filter
method without explicitely open Microsoft.FSharp.Core
namespace:
// Commenting following line will break the code!
open Microsoft.FSharp.Core
let v1 = Some 42
let v2 = v1 |> Option.filter (fun v -> v > 40)
printfn "v2 is: %A" v2
In most cases we can't use functions from module without opening appropriate namespace.
F# compiler "opens" some predefine (core) namespace automatically (like Microsoft.FSharp.Core
), this will not bring into the scope methods from "module extensions" and we still should open core namespaces manually.
My question is: Is there any workarounds?
Or the best way to extend "core" modules is to create such extensions in custom namespace and open this namespace manually?
// Lets custom Option module in our custom namespace
module CustomNamespace.Option
let filter predicate op = ...
// On the client side lets open our custom namespace.
// After that we can use both Option modules simultaneously!
open CustomNamespace
let v1 = Some 42
let b =
v1 |> Option.filter (fun v -> v > 40) // using CustomNamespace.Option
|> Option.isSome // using Microsoft.FSharp.Core.Option
For production code I would do what the Taha's answer suggests: create your own module and open/alias it as necessary. Most of your life as programmer will be spent reading code. It can be quite frustrating reading F# code where it is not clear where methods come from.
That being said, I was surprised to find that this works:
namespace Microsoft.FSharp.Core
module Option =
let filter predicate op =
match op with
| Some(v) -> if predicate(v) then Some(v) else None
| None -> None
namespace USERCODE
module Option = Microsoft.FSharp.Core.Option
module M =
let test () =
Some 1
|> Option.filter (fun x -> x > 0)
|> Option.map (fun x -> x + 1)
It does not remove the need to write something in the head of your files, but it does work around needing to open a namespace. Not relevant for Microsoft.FSharp.Core
as it is always open by default, but helpful for other namespaces.
In order to extend an F# module create another with the same name:
module Option =
let filter predicate op =
match op with
| Some v -> match predicate v with true -> Some v | false -> None
| None -> None
let v1 = Some 42
let v2 = v1 |> Option.filter (fun v -> v > 40)
printfn "v2 is: %A" v2
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With