Record methods in F# - f#

I have written a simple example for my scenario. I create a record type Switch
type State =
| On
| Off
with
member this.flip =
match this with
| On -> Off
| Off -> On
type Switch = { State : State }
and then I write a function that creates a copy of the record with one element changed
let flip switch = { switch with State = switch.State.flip }
To flip many successive times I write
let flipMany times switch =
[1 .. times]
|> List.fold (fun (sw : Switch) _ -> flip sw) switch
If I want put these two functions on the record as methods, I write instead
type Switch =
{ State : State }
member this.flip =
{ this with State = this.State.flip }
member this.flipMany times =
[1 .. times]
|> List.fold (fun (sw : Switch) _ -> sw.flip) this
Is there anything wrong with doing this? Is it equally efficient? It feels a bit uncomfortable calling the function sw.flip on a different object every single time.
Edit: this is just a simple example in order to explain my question. My question is on how the function flipMany compares with the flipMany method on the record. The implementation might be naive, but it is the same in both of cases.

Your intent can be implemented as simple as
let flipMany times switch =
match (times % 2) with
| 1 -> { switch with State = switch.State.flip }
| _ -> switch
type Switch =
{ State : State }
member this.Flip = { this with State = this.State.flip }
member this.FlipMany times =
match (times % 2) with | 1 -> this.Flip | _ -> this
In the broader context of comparing a static function versus an object's method the idiomatic way would be sticking to function option. A function has explicit arguments and must not depend on any side state, but state of arguments, to produce an idempotent result value. On the contrary, an object method implicitly gets an instance of the class as an argument and may derive result value not just from arguments, but based on the state of other class fields too, which is not in line with idempotency property of a pure function.
To feel this difference better it may help reading thru F# Components Design Guidelines and exploring F# Core libraries design.

Related

Pattern matching casting types

I am a newbie in F# and have been following guides to try to make a piece of code work but it hasn't.
I create types of single and coop sports through inheritance.
Then I use pattern matching to know the type and, if it is a coop sport, get also the number of players. Then rank each accordingly.
However, I have been getting errors. I followed Microsoft examples on this and I don't really understand the errors. I don't have a functional programming background.
type Sport (name: string) =
member x.Name = name
type Individual(name: string) =
inherit Sport(name)
type Team(name: string, numberOfPlayers : int) =
inherit Sport(name)
member x.numberOfPlayers = numberOfPlayers
let MK = new Individual("Combate Mortal")
let SF = new Individual("Lutadores de Rua")
let Tk = new Individual("Tekken Chupa")
let MvC = new Team("Marvel Contra Capcom", 3)
let Dbz = new Team("Bolas do Dragao", 3)
let interpretSport (sport:string) (players:int) =
match sport with
| "Combate Mortal" -> printfn "Rank1"
| "Lutadores de Rua" -> printfn "Rank2"
| "Tekken Chupa" -> printfn "Rank3"
| "Bolas do Dragao" -> printfn "Rank4. No of players: %d " players
| "Marvel Contra Capcom" -> printfn "Rank5. No of players: %d" players
| _ -> printfn "not a sport in our list..."
let matchSport (sport:Sport) =
match sport with
| :? Individual -> interpretSport(sport.Name)
| :? Team as teamSport -> interpretSport(teamSport.Name,teamSport.numberOfPlayers)
| _ -> printfn "not a sport"
matchSport(MK)
matchSport(SF)
matchSport(Tk)
matchSport(MvC)
matchSport(Dbz)
1st error when calling function with more than 1 argument:
2nd error when printing:
The question has already been answered, but because the asker says he is a newby in F#, maybe it's worth to iterate a little.
To begin, you define a function with two parameters:
let interpreteSport (sport:string) (player:int) =
In F#, there is no notion of optional parameters in the same sense that they exist in C#, so if you declare a function with two parameters, and you want to invoke it, and get its return value, you must supply all the parameters you put in its definition.
So in the first branch of your match expression, when you write:
:? Individual -> interpretSport(sport.Name)
you are making an error, passing only one parameter to a function that takes two.
But wait! Why the compiler don't alert you with an error saying you are calling a function with one parameter when it expects two?
Because it turns out that what you write, even if it does not call the interpreteSport function as you believed, it's a perfect valid expression in F#.
What it returns is an expression called "partially applied function", that is, a function that has received its first parameter, and is waiting for another one.
If you assign the result of such an expression to a value, let's say:
let parzFun = interpretSport sport.Name
you can then pass this value around in your code and, when you are ready to supply the missing parameter, evaluate it like this:
let result = parzFun 1
That's what the compiler is telling you when it talks about 'int -> unit': function signatures in F# are given in this form:
a -> b -> c -> d -> retval, where a, b, c, d etc. are the types of the parameters, and retVal the return value.
Your interpreteSport function has a signature of: string -> int -> unit, where unit is the special type that means 'no value', similar to C# void, but with the big difference that unit is an expression that you can correctly assign to a value, while void is just a keyword, and you cannot assign a variable to void in C#.
OK, so, when you call your function passing only the first parameter (a string), what you obtain is an expression of type int -> unit, that is another function that expects and integer and returns unit.
Because this expression is in a branch of a match expression, and because all the branches of a match expression must return the same type, the other 2 branches are also expected to return an int -> unit function, what it's not, and that explain your second error.
More on this in a moment, but before, we must look at the first error reported by the compiler, caused by this line of code:
:? Team as teamSport -> interpretSport(teamSport.Name,teamSport.numberOfPlayers)
Here, you are thinking your are calling your function with 2 parameters, but your are actually not: when you put 2 values in parenthesis, separated by a comma, you are creating a tuple, that is, a single value composed of two or more values. It's like your are passing again only the first parameter, but now with the wrong type: the first parameter of you function is a string, and you are instead passing a tuple: ('a * 'b) is how F# represents tuples: that means a single value composed of a value of type 'a (generic, in your case string) and another of type 'b (generic, in your case integer).
To call your function correctly you must call it so:
:? Team as teamSport -> interpretSport teamSport.Name teamSport.numberOfPlayers
But even if you limit yourself to this correction you will have all the same the second error because, remember, the first expression of your match returns a partially applied funcion, so int -> unit (a function that expects an integer and returns a unit) while your second and your third expressions are now of type unit, because they actually call two functions that return unit (interpreteSport and printfn). To completely fix your code, as has already been said in other answers, you must supply the missing integer parameter to the first call, so:
let matchSport (sport:Sport) =
match sport with
| :? Individual -> interpretSport sport.Name 1
| :? Team as teamSport -> interpretSport teamSport.Name teamSport.numberOfPlayers
| _ -> printfn "not a sport"
If this is a F# learning exercise then it's best to avoid classes and inheritance completely. The fundamental idiomatic F# types are records and discriminated unions.
The intent of your code is not clear to me at all, but I have attempted to refactor to remove the use of classes:
type Players =
| Individual
| Team of numberOfPlayers:int
type Sport = { Name : string; Players : Players }
let MK = { Name = "Combate Mortal"; Players = Individual }
let SF = { Name = "Lutadores de Rua"; Players = Individual }
let Tk = { Name = "Tekken Chupa"; Players = Individual }
let MvC = { Name = "Marvel Contra Capcom"; Players = Team 3 }
let Dbz = { Name = "Bolas do Dragao"; Players = Team 3 }
let interpretSport (sport:Sport) =
let players =
match sport.Players with
| Individual -> ""
| Team numberOfPlayers -> sprintf ". No of players: %d" numberOfPlayers
let rank =
match sport.Name with
| "Combate Mortal" -> Some 1
| "Lutadores de Rua" -> Some 2
| "Tekken Chupa" -> Some 3
| "Bolas do Dragao" -> Some 4
| "Marvel Contra Capcom" -> Some 5
| _ -> None
match rank with
| Some r -> printfn "Rank%d%s" r players
| None -> printfn "not a sport in our list..."
Your function interpretSport has two arguments but your first call to it has only one. Try calling it like so:
| :? Individual -> interpretSport sport.Name 1
Also, the second call uses tupled parameters but the function is declared to take curried parameters. Try calling it like so:
| :? Team as teamSport -> interpretSport teamSport.Name teamSport.numberOfPlayers
There are several small problems with your code. The most obvious is in matchSport, you are calling interpretSport in an uncurried style, with an argument tuple. The call should look like:
Team as teamSport -> interpretSport teamSport.Name teamSport.numberOfPlayers
However, that's a problem, because on the first case of the pattern matching you call interpretSport with only one argument, so you partially apply it and you get a type int -> unit, but when you fully apply it on the second case you get unit, and of course all types of the pattern matching cases must match. The cheapest solution would be to add a 1 to your call on the first case like this:
Individual -> interpretSport sport.Name 1
But you probably want to use the sports you bound before (maybe in a list you give as a parameter) to do the checking. It is in general a bad idea (in functional programming and elsewhere) to hard-code that many strings, you probably want to do some kind of association List, or Map of the Sports to the Ranks, then fold over the sports List and match when found with individual or team and then print whatever the Map gives you for that case. This would be shorter and more extensible.

How to memoize the result of a property of a Discriminated Union in F#

I have a Discriminated Union ("DU") type and a property OR method which computes something based on the DU instance. I am trying to achieve a pattern where the instance property performs the calculation the first time it is requested and then remembers the result - akin to a Singleton Pattern in Object Oriented Terms.
I am finding this challenging without the aid of a local instance variable to store the state of things...
I have tried simple memoization of a method but I then run into the problem of not having anywhere (in the instance) to store the memoized result.
Note: there will be many instances of this DU type in my application.
Code
// Terrible mutable variable needed alongside the DU to achieve a singleton-like pattern
let mutable result: int option = None
type DU =
| Good of int
| Bad of int
with
// behaves like a Singleton
member this.GetSomething =
match result with
| None ->
printfn "Big bad side-effect to let us know it's a first time"
// big bad calculation that we only want to do once
let x = 1 + 1
// "memoize" it
result <- Some x
x
| Some y -> y
let instance = Good 1
let f1 = instance.GetSomething // first time
let f2 = instance.GetSomething // second call - no side effect1
You can't memoize inside of an immutable value, because memoization involves changing and maintaining state.
Obviously, you can do it outside of an immutable value:
let smth = getSomething "foo"
As long as you reuse smth instead of calling getSomething "foo" again, you've essentially memoized the result. This is safe if getSomething is referentially transparent; otherwise, it's not.
From the sample code posted in the OP, it looks more like you're looking for lazy initialization, which you can get from the Lazy<T> class. You'll still need an object in which to store the Lazy<T> instance, though.
open System
type MyObject() =
let result =
lazy
printfn "Big bad side-effect to let us know it's a first time"
// big bad calculation that we only want to do once
1 + 1
member this.GetSomething = result.Value
As you can see, in F# you can also use lazy expressions for this.
> let mo = MyObject ();;
val mo : MyObject
> let smth1 = mo.GetSomething;;
Big bad side-effect to let us know it's a first time
val smth1 : int = 2
> let smth2 = mo.GetSomething;;
val smth2 : int = 2
The MyObject class may look immutable, but that's only because state is being kept inside of the lazy expression.
This way it is possible to have a lazy inside a DU.
Because the type is Lazy.
type DU =
| Good of Lazy<int> // Lazy not lazy
| Bad of Lazy<int>
type MyObject() =
let result =
lazy(
printfn "Big bad side-effect to let us know it's a first time"
// big bad calculation that we only want to do once
1 + 1) |> Good
member this.GetSomething = result
let mo = MyObject()
let f() =
match mo.GetSomething with
| Good x -> x.Value
| Bad y -> y.Value
f()
f()
Output
Big bad side-effect to let us know it's a first time
val it : int = 2
>
val it : int = 2

How to implement delay in the maybe computation builder?

Here is what I have so far:
type Maybe<'a> = option<'a>
let succeed x = Some(x)
let fail = None
let bind rest p =
match p with
| None -> fail
| Some r -> rest r
let rec whileLoop cond body =
if cond() then
match body() with
| Some() ->
whileLoop cond body
| None ->
fail
else
succeed()
let forLoop (xs : 'T seq) f =
using (xs.GetEnumerator()) (fun it ->
whileLoop
(fun () -> it.MoveNext())
(fun () -> it.Current |> f)
)
whileLoop works fine to support for loops, but I don't see how to get while loops supported. Part of the problem is that the translation of while loops uses delay, which I could not figure out in this case. The obvious implementation below is probably wrong, as it does not delay the computation, but runs it instead!
let delay f = f()
Not having delay also hinders try...with and try...finally.
There are actually two different ways of implementing continuation builders in F#. One is to represent delayed computations using the monadic type (if it supports some way of representing delayed computations, like Async<'T> or the unit -> option<'T> type as shown by kkm.
However, you can also use the flexibility of F# computation expressions and use a different type as a return value of Delay. Then you need to modify the Combine operation accordingly and also implement Run member, but it all works out quite nicely:
type OptionBuilder() =
member x.Bind(v, f) = Option.bind f v
member x.Return(v) = Some v
member x.Zero() = Some ()
member x.Combine(v, f:unit -> _) = Option.bind f v
member x.Delay(f : unit -> 'T) = f
member x.Run(f) = f()
member x.While(cond, f) =
if cond() then x.Bind(f(), fun _ -> x.While(cond, f))
else x.Zero()
let maybe = OptionBuilder()
The trick is that F# compiler uses Delay when you have a computation that needs to be delayed - that is: 1) to wrap the whole computation, 2) when you sequentially compose computations, e.g. using if inside the computation and 3) to delay bodies of while or for.
In the above definition, the Delay member returns unit -> M<'a> instead of M<'a>, but that's perfectly fine because Combine and While take unit -> M<'a> as their second argument. Moreover, by adding Run that evaluates the function, the result of maybe { .. } block (a delayed function) is evaluated, because the whole block is passed to Run:
// As usual, the type of 'res' is 'Option<int>'
let res = maybe {
// The whole body is passed to `Delay` and then to `Run`
let! a = Some 3
let b = ref 0
while !b < 10 do
let! n = Some () // This body will be delayed & passed to While
incr b
if a = 3 then printfn "got 3"
else printfn "got something else"
// Code following `if` is delayed and passed to Combine
return a }
This is a way to define computation builder for non-delayed types that is most likely more efficient than wrapping type inside a function (as in kkm's solution) and it does not require defining a special delayed version of the type.
Note that this problem does not happen in e.g. Haskell, because that is a lazy language, so it does not need to delay computations explicitly. I think that the F# translation is quite elegant as it allows dealing with both types that are delayed (using Delay that returns M<'a>) and types that represent just an immediate result (using Delay that returns a function & Run).
According to monadic identities, your delay should always be equivalent to
let delay f = bind (return ()) f
Since
val bind : M<'T> -> ('T -> M<'R>) -> M<'R>
val return : 'T -> M<'T>
the delay has the signature of
val delay : (unit -> M<'R>) -> M<'R>
'T being type-bound to unit. Note that your bind function has its arguments reversed from the customary order bind p rest. This is technically same but does complicate reading code.
Since you are defining the monadic type as type Maybe<'a> = option<'a>, there is no delaying a computation, as the type does not wrap any computation at all, only a value. So you definition of delay as let delay f = f() is theoretically correct. But it is not adequate for a while loop: the "body" of the loop will be computed before its "test condition," really before the bind is bound. To avoid this, you redefine your monad with an extra layer of delay: instead of wrapping a value, you wrap a computation that takes a unit and computes the value.
type Maybe<'a> = unit -> option<'a>
let return x = fun () -> Some(x)
let fail = fun() -> None
let bind p rest =
match p() with
| None -> fail
| Some r -> rest r
Note that the wrapped computation is not run until inside the bind function, i. e. not run until after the arguments to bind are bound themselves.
With the above expression, delay is correctly simplified to
let delay f = fun () -> f()

Rewriting simple C# nested class

What would be an elegant way to implement the functionality of this nested class in F#?
private class Aliaser {
private int _count;
internal Aliaser() { }
internal string GetNextAlias() {
return "t" + (_count++).ToString();
}
}
This was my first attempt, but it feels like there should be a sexy one-liner for this:
let aliases = (Seq.initInfinite (sprintf "t%d")).GetEnumerator()
let getNextAlias() =
aliases.MoveNext() |> ignore
aliases.Current
The usual way of writing is to create a function with local state captured in a closure:
let getNextAlias =
let count = ref 0
(fun () ->
count := !count + 1;
sprintf "t%d" (!count))
The type of getNextAlias is simply unit -> string and when you call it repeatedly, it returns strings "t1", "t2", ... This relies on mutable state, but the mutable state is hidden from the user.
Regarding whether you can do this without mutable state - the simple answer is NO, because when you call a purely functional function with the same parameter twice, it must return the same result. Thus, you'd have to write something with the following structure:
let alias, state1 = getNextAlias state0
printf "first alias %s" alias
let alias, state2 = getNextAlias state1
printf "second alias %s" alias
// ...
As you can see, you'd need to keep some state and maintain it through the whole code. In F#, the standard way of dealing with this is to use mutable state. In Haskell, you could use State monad, which allows you to hide the passing of the state. Using the implementation from this question, you could write something like:
let getNextAlias = state {
let! n = getState
do! setState (n + 1)
return sprintf "t%d" n }
let program =
state {
let! alias1 = getNextAlias()
let! alias2 = getNextAlias()
// ...
}
execute progam 0 // execute with initial state
This is quite similar to other computations such as lazy or seq, actually - computations in the state { .. } block have some state and you can execute them by providing initial value of the state. However, unless you have good reasons for requiring purely functional solution, I'd prefer the first version for practical F# programming.
Here is the quick and dirty translation
type Aliaser () =
let mutable _count = 0
member x.GetNextAlias() =
let value = _count.ToString()
_count <- _count + 1
"t" + value
A more functional approach without state is to use continuations.
let createAliaser callWithValue =
let rec inner count =
let value = "t" + (count.ToString())
callWithValue value (fun () -> inner (count + 1))
inner 1
This is a declaration which will call the function callWithValue with both the value and the function to execute to repeat with the next value.
And here's an example using it
let main () =
let inner value (next : unit -> unit )=
printfn "Value: %s" value
let input = System.Console.ReadLine()
if input <> "quit" then next()
createAliaser inner
main()
I would use Seq.unfold : (('a -> ('b * 'a) option) -> 'a -> seq<'b>) to generate the aliases.
Implemented as:
let alias =
Seq.unfold (fun count -> Some(sprintf "t%i" count, count+1)) 0

Cyclic lists in F#

Is it just me, or does F# not cater for cyclic lists?
I looked at the FSharpList<T> class via reflector, and noticed, that neither the 'structural equals' or the length methods check for cycles. I can only guess if 2 such primitive functions does not check, that most list functions would not do this either.
If cyclic lists are not supported, why is that?
Thanks
PS: Am I even looking at the right list class?
There are many different lists/collection types in F#.
F# list type. As Chris said, you cannot initialize a recursive value of this type, because the type is not lazy and not mutable (Immutability means that you have to create it at once and the fact that it's not lazy means that you can't use F# recursive values using let rec). As ssp said, you could use Reflection to hack it, but that's probably a case that we don't want to discuss.
Another type is seq (which is actually IEnumerable) or the LazyList type from PowerPack. These are lazy, so you can use let rec to create a cyclic value. However, (as far as I know) none of the functions working with them take cyclic lists into account - if you create a cyclic list, it simply means that you're creating an infinite list, so the result of (e.g.) map will be a potentially infinite list.
Here is an example for LazyList type:
#r "FSharp.PowerPack.dll"
// Valid use of value recursion
let rec ones = LazyList.consDelayed 1 (fun () -> ones)
Seq.take 5 l // Gives [1; 1; 1; 1; 1]
The question is what data types can you define yourself. Chris shows a mutable list and if you write operations that modify it, they will affect the entire list (if you interpret it as an infinite data structure).
You can also define a lazy (potentionally cyclic) data type and implement operations that handle cycles, so when you create a cyclic list and project it into another list, it will create cyclic list as a result (and not a potentionally infinite data structure).
The type declaration may look like this (I'm using object type, so that we can use reference equality when checking for cycles):
type CyclicListValue<'a> =
Nil | Cons of 'a * Lazy<CyclicList<'a>>
and CyclicList<'a>(value:CyclicListValue<'a>) =
member x.Value = value
The following map function handles cycles - if you give it a cyclic list, it will return a newly created list with the same cyclic structure:
let map f (cl:CyclicList<_>) =
// 'start' is the first element of the list (used for cycle checking)
// 'l' is the list we're processing
// 'lazyRes' is a function that returns the first cell of the resulting list
// (which is not available on the first call, but can be accessed
// later, because the list is constructed lazily)
let rec mapAux start (l:CyclicList<_>) lazyRes =
match l.Value with
| Nil -> new CyclicList<_>(Nil)
| Cons(v, rest) when rest.Value = start -> lazyRes()
| Cons(v, rest) ->
let value = Cons(f v, lazy mapAux start rest.Value lazyRes)
new CyclicList<_>(value)
let rec res = mapAux cl cl (fun () -> res)
res
The F# list type is essentially a linked list, where each node has a 'next'. This in theory would allow you to create cycles. However, F# lists are immutable. So you could never 'make' this cycle by mutation, you would have to do it at construction time. (Since you couldn't update the last node to loop around to the front.)
You could write this to do it, however the compiler specifically prevents it:
let rec x = 1 :: 2 :: 3 :: x;;
let rec x = 1 :: 2 :: 3 :: x;;
------------------------^^
stdin(1,25): error FS0260: Recursive values cannot appear directly as a construction of the type 'List`1' within a recursive binding. This feature has been removed from the F# language. Consider using a record instead.
If you do want to create a cycle, you could do the following:
> type CustomListNode = { Value : int; mutable Next : CustomListNode option };;
type CustomListNode =
{Value: int;
mutable Next: CustomListNode option;}
> let head = { Value = 1; Next = None };;
val head : CustomListNode = {Value = 1;
Next = null;}
> let head2 = { Value = 2; Next = Some(head) } ;;
val head2 : CustomListNode = {Value = 2;
Next = Some {Value = 1;
Next = null;};}
> head.Next <- Some(head2);;
val it : unit = ()
> head;;
val it : CustomListNode = {Value = 1;
Next = Some {Value = 2;
Next = Some ...;};}
The answer is same for all languages with tail-call optimization support and first-class functions (function types) support: it's so easy to emulate cyclic structures.
let rec x = seq { yield 1; yield! x};;
It's simplest way to emulate that structure by using laziness of seq.
Of course you can hack list representation as described here.
As was said before, your problem here is that the list type is immutable, and for a list to be cyclic you'd have to have it stick itself into its last element, so that doesn't work. You can use sequences, of course.
If you have an existing list and want to create an infinite sequence on top of it that cycles through the list's elements, here's how you could do it:
let round_robin lst =
let rec inner_rr l =
seq {
match l with
| [] ->
yield! inner_rr lst
| h::t ->
yield h
yield! inner_rr t
}
if lst.IsEmpty then Seq.empty else inner_rr []
let listcycler_sequence = round_robin [1;2;3;4;5;6]

Resources