How to implement variable arguments in F# - f#

I want to implement a F# function which may accept 1 or 2 arguments. I would like to use the function like this:
let foo = ...
foo "a"
foo "a" "b"
Both the arguments can be the same type. I read the pages about match pattern, active pattern, but cannot find one works for me.

I believe this is due to some of the underlying .Net features, but I think you have to use a class with overloaded methods - something like
type t() =
static member foo a = "one arg"
static member foo (a,b) = "two args"

On a type member, you can use optional params:
type Helper private () =
static member foo (input1, ?input2) =
let input2 = defaultArg input2 "b"
input1, input2
To call this method:
Helper.foo("a")
Helper.foo("a", "b")
Is this what you're after?
You can't use optional params on a function though, unfortunately.

In addition to the other answers, here are a few more "almost solutions". They are not strictly what you wanted, but are worth knowing anyway.
Using a list (or an array) and pattern matching:
let f = function
| [a, b] -> ...
| [a] -> ...
| [] -> failwith "too few arguments"
| _ -> failwith "too many arguments"
f ["a"]
f ["a" ; "b"]
Problems: parameters are not named, not clear from function signature how many parameters it takes.
Using a record to pass all optional parameters:
type FParams = { a : string; b : string }
let fdefault = { a = "a" ; b = "b" }
let f (pars: FParams) = ...
f { fdefault with b = "c" }
Problem: a is also optional, which is not what you wanted. Can be useful though.

In addition to the other answers, you might also be able to do what you want via partial application and currying. Like this:
let foo a b =
a + b
let foo2 a =
foo 1 a;;
Obviously you'd want to fix the first parameter in the call to foo within foo2 to whatever default you want.

Related

What is missing using interfaces compared to true type-classes?

F# does not (currently) support type-classes. However, F# does support the OOP aspects of C#.
I was wondering, what is lost doing this approach compared to true type-classes?
// A concrete type
type Foo =
{
Foo : int
}
// "Trait" for things that can be shown
type IShowable =
abstract member Show : unit -> string
module Showable =
let show (showable : IShowable) =
showable.Show()
// "Witness" of IShowable for Foo
module Foo =
let asShowable (foo : Foo) =
{
new IShowable with
member this.Show() = string foo.Foo
}
// Slightly awkward usage
{ Foo = 123 }
|> Foo.asShowable
|> Showable.show
|> printfn "%s"
Your suggestion works for simple typeclasses that operate on a single value of a type, like Show. However, what happens when you need a typeclass that isn't so object-oriented? For example, when we want to add two numbers, neither one corresponds to OO's this object:
// not real F#
typeclass Numeric<'a> = // e.g. Numeric<int> or Numeric<float>
abstract member (+) : 'a -> 'a -> 'a // e.g. 2 + 3 = 5 or 2.0 + 3.0 = 5.0
...
Also, keep in mind that many useful typeclasses require higher-kinded types. For example, consider the monad typeclass, which would look something like this:
// not real F#
typeclass Monad<'m<_>> = // e.g. Monad<Option<_>> or Monad<Async<_>>
abstract member Return<'a> : 'a -> 'm<'a>
abstract member Bind<'a, 'b> : 'm<'a> -> ('a -> 'm<'b>) -> 'm<'b>
There's no good way to do this with .NET interfaces.
Higher-kinded type classes are indeed impossible to model with interfaces, but that's just because F# does not support higher-kindedness, not because of type classes themselves.
The deeper thing to note is that your encoding isn't actually correct. Sure, if you just need to call show directly, you can do asShowable like that, but that's just the simplest case. Imagine you needed to pass the value to another function that wanted to show it later? And then imagine it was a list of values, not a single one:
let needsToShow (showable: IShowable) (xs: 'a list) =
xs |> List.iter (fun x -> ??? how do I show `x` ???)
No, this wouldn't do of course. The key is that Show should be a function 'a -> string, not unit -> string. And this means that IShowable itself should be generic:
// Haskell: class Showable a where show :: a -> String
type IShowable<'a> with
abstract member Show : 'a -> string
// Haskell: instance Showable Foo where show (Foo i) = show i
module Foo =
let showable = { new IShowable<Foo> with member _.Show foo = string foo.Foo }
// Haskell: needsToShow :: Show a => [a] -> IO ()
let needsToShow (showable: IShowable<'a>) (xs: 'a list) =
xs |> List.iter (fun x -> printfn "%s" (showable.Show x))
// Haskell: needsToShow [Foo 1, Foo 42]
needsToShow Foo.showable [ { Foo: 1 }; { Foo: 42 } ]
And this is, essentially, what type classes are: they're indeed merely dictionaries of functions that are passed everywhere as extra parameters. Every type has such dictionary either available right away (like Foo above) or constructable from other such dictionaries, e.g.:
type Bar<'a> = Bar of 'a
// Haskell: instance Show a => Show (Bar a) where show (Bar a) = "Bar: " <> show a
module Bar =
let showable (showA: IShowable<'a>) =
{ new IShowable<Bar<'a>> with member _.Show (Bar a) = "Bar: " + showA.Show a }
This is completely equivalent to type classes. And in fact, this is exactly how they're implemented in languages like Haskell or PureScript in the first place: like dictionaries of functions being passed as extra parameters. It's not a coincidence that constraints on function type signatures even kinda look like parameters - just with a fat arrow instead of a thin one.
The only real difference is that in F# you have to do that yourself, while in Haskell the compiler figures out all the instances and passes them for you.
And this difference turns out to be kind of important in practice. I mean, sure, for such a simple example as Show for the immediate parameter, you can just pass the damn instance yourself. And even if it's more complicated, I guess you could suck it up and pass a dozen extra parameters.
But where this gets really inconvenient is operators. Operators are functions too, but with operators there is nowhere to stick an extra parameter (or dozen). Check this out:
x = getY >>= \y -> getZ y <&> \z -> y + 42 > z
Here I used four operators from four different classes:
>>= comes from Monad
<&> from Functor
+ from Num
> from Ord
An equivalent in F# with passing instances manually might look something like:
let x =
bind Foo.monad getY <| fun y ->
map Bar.functor (getZ y) <| fun z ->
gt Int.ord (add Int.num y 42) z
Having to do that everywhere is quite unreasonable, you have to agree.
And this is why many F# operators either use SRTPs (e.g. +) or rely on "known" interfaces (e.g. <) - all so you don't have to pass instances manually.

How to access "base" in Discriminated Union method override?

I have a DU and I'm overriding the Equals method. Based on the current DU value, I would like to call the base equality method or my custom one. However, it's not letting me access "base". Any idea on how to work around this?
type Test =
| A of string
| B of int64
override this.Equals(other) =
let other' = other :?> Test
match other' with
| A str -> str = "a"
| B i -> base.Equals this other //how do I do this?
First, any F# discriminated union will have obj as base class, so just use obj.Equals.
Second, Equals is a .NET method, not an F# function, so its arguments must be given in a tupled form - i.e. Equals(x,y) instead of Equals x y.
Finally, if you implement a custom Equals, you also need to add [<CustomEquality; NoComparison>]
So:
[<CustomEquality; NoComparison>]
type Test =
| A of string
| B of int64
override this.Equals(other) =
let other' = other :?> Test
match other' with
| A str -> str = "a"
| B i -> obj.Equals(this, other)

F# Use generic type as pattern discriminator

If there's another way to achieve what I'm trying to do below, please let me know. Suppose I have the following sample code
type FooBar =
| Foo
| Bar
let foobars = [Bar;Foo;Bar]
let isFoo item =
match item with
| Foo _ -> true
| _ -> false
foobars |> Seq.filter isFoo
I want to write a generic/higher-order version of isFoo that allows me to filter my list based on all other types of the discriminated union (Bar in this case).
Something like the following, where 'a can be either Foo or Bar
let is<'a> item =
match item with
| a _ -> true
| _ -> false
However, this attempt yields the following error:
error FS0039: The pattern discriminator 'a' is not defined
If you just want to filter a list, then the easiest option is to use function to write standard pattern matching:
[ Foo; Bar; Foo ]
|> List.filter (function Foo -> true | _ -> false)
If you wanted to write some more complicated generic function that checks for a case and then does something else, then the easiest option (that will work in general) is to take a predicate that returns true or false:
let is cond item =
if cond item then
true
else
false
// You can create a predicate using `function` syntax
is (function Foo -> true | _ -> false) <argument>
In your specific example, you have a discriminated union where none of the cases has any parameters. This is probably an unrealistic simplification, but if you only care about discriminated unions without parameters, then you can just use the cases as values and compare them:
let is case item =
if case = item then
true
else
false
// You can just pass it 'Foo' as the first parameter to
// `is` and use partial function application
[ Foo; Bar; Foo ]
|> List.filter (is Foo)
// In fact, you can use the built-in equality test operator
[ Foo; Bar; Foo ] |> List.filter ((=) Foo)
This last method will not work if you have more complicated discriminated union where some cases have parameters, so it is probably not very useful. For example, if you have a list of option values:
let opts = [ Some(42); None; Some(32) ]
opts |> List.filter (is Some) // ERROR - because here you give 'is' a constructor
// 'Some' instead of a value that can be compared.
You could do various tricks using Reflection (to check for cases with a specified name) and you could also use F# quotations to get a bit nicer and safer syntax, but I do not think that's worth it, because using pattern matching using function gives you quite clear code.
EDIT - Just out of curiosity, a solution that uses reflection (and is slow, not type safe and nobody should actually use it in practice unless you really know what you're doing) could look like this:
open Microsoft.FSharp.Reflection
open Microsoft.FSharp.Quotations
let is (q:Expr) value =
match q with
| Patterns.Lambda(_, Patterns.NewUnionCase(case, _))
| Patterns.NewUnionCase(case, _) ->
let actualCase, _ = FSharpValue.GetUnionFields(value, value.GetType())
actualCase = case
| _ -> failwith "Wrong argument"
It uses quotations to identify the union case, so you can then write something like this:
type Case = Foo of int | Bar of string | Zoo
[ Foo 42; Zoo; Bar "hi"; Foo 32; Zoo ]
|> List.filter (is <# Foo #>)
As long as union cases accept the same set of parameters, you can pass a constructor as an argument and reconstruct DUs for comparison.
It looks more appealing when Foo and Bar have parameters:
type FooBar = Foo of int | Bar of int
let is constr item =
match item with
| Foo x when item = constr x -> true
| Bar x when item = constr x -> true
| _ -> false
In your example, constructors have no argument. So you can write is in a simpler way:
type FooBar = Foo | Bar
let is constr item = item = constr
[Bar; Foo; Bar] |> Seq.filter (is Foo)

Generic extraction from a constructor

In F# and OCaml I wind up writing a lot of code like
type C = Blah of Whatever
let d = Blah (createWhatever ()) // so d is type C
...
let x = match d with | Blah b -> b
What I'd like is this
...
let x = peel d
Where peel would work for any constructor/discriminator.
Surely I'm not the only one annoyed by this.
edit:
Good answers, but I don't have the rep to vote on them.
How about this situation?
member self.Length = match self with | L lab -> lab.Length
It is not possible to do that safely : if peel was a function, what would be its type ? It cannot be typed and therefore cannot be a "good guy" in the language.
You may :
use reflection (in F#) or type-breaking functions (in OCaml it's the Obj module), but you will get something unsafe with an imprecise type, so it's rather ugly and "use at your own risk"
use metaprogramming to generate different versions of peel at each type for you. For example, using the type-conv OCaml tool, you may have type blah = Blah of something define a function peel_blah implicitly, and type foo = Foo of something define peel_foo.
The better solution imho is... not to need such a peel in the first place. I see two possibilities:
You may use clever patterns instead of a function : by using let (Blah whatever) = f x, or fun (Blah whatever) -> ..., you don't need an unpacking function anymore.
Or you may, instead of writing type blah = Blah of what, write
type blah = (blah_tag * whatever) and blah_tag = Blah
This way, you don't have a sum type but a product type (you write (Blah, whatever)), and your peel is just snd. You still have a different (incompatible) type for each blah, foo etc, but a uniform access interface.
As mentioned, the let is convenient to do a pattern matching.
If you want to access the value in the middle of an expression, where patterns are not allowed, I suggest adding a member to the types:
type C = Blah of int
with member c.Value = match c with Blah x -> x
let x = Blah 5
let y = Blah 2
let sum = x.Value + y.Value
I would write this instead:
type C = Blah of Whatever
let d = Blah (createWhatever ()) // so d is type C
...
let (Blah x) = d
For your second situation, I like Laurent's member x.Value = match x with Blah v -> v.
Works for DUs...will need tweaking to work with class constructors:
open Microsoft.FSharp.Reflection
let peel d =
if obj.ReferenceEquals(d, null) then nullArg "d"
let ty = d.GetType()
if FSharpType.IsUnion(ty) then
match FSharpValue.GetUnionFields(d, ty) with
| _, [| value |] -> unbox value
| _ -> failwith "more than one field"
else failwith "not a union type"
By the way: I wouldn't typically do something like this, but since you asked...

F# block arguments

C# has anonymous delegates. So I can write:
public vois foo(string d, Action t){
t();
}
In ruby:
def foo d
yield
end
How to do the same in F#? Prefered syntax is:
foo "dfdfdf" { do something here }
Thanks
Your first example isn't an anonymous method -- it's just passing and calling through a delegate (which might refer to a named or an anonymous method). To do this in F#, just provide and call a function argument:
let foo n f = f n
let square n = n * n
let result = foo 123 square
printfn "%A" result
To create the equivalent of an anonymous method in F#, use the fun keyword:
let result2 = foo 123 (fun n -> n * n)
Have a look at this article about Higher Order Functions in F#. Higher Order Functions are functions which accept other functions as arguments, and sound like the concept you are describing.
open System
// create a function that expects an Action delegate and executes it
let foo (actionDelegate:Action) (s:String) = actionDelegate.Invoke();
// create a function that meets Action delegate
let ActionFunction param = Console.Write("Action in action")
// call foo passing ActionFunction
foo (new Action(ActionFunction)) "my string"

Resources