Reputation: 29785
Please, help an F# beginner understand this! I have the following F# code (which I've just created to help me learn, so I realise it's probably terrible):
type Account = {
ID: Guid
Name: string
};
module Accounts =
let mutable accounts:Account list = []
// Why does this always return empty?
let lst =
accounts
let load id =
accounts |> List.find(fun a-> a.ID = id)
let save account =
accounts <- account::accounts
Accounts.save { ID = Guid.NewGuid(); Name = "Account One"}
let id = Guid.NewGuid()
Accounts.save { ID = id; Name = "Account Two"}
let account = Accounts.load id
If I write out the value of account
at this stage (after the above code), I see the Account
record I expect (Account Two), and if I dump Accounts.accounts
, I can see that the mutable list contains both Account
records.
So why does Account.lst
always return an empty list, even though I can see that the list definitely isn't empty?
Upvotes: 2
Views: 103
Reputation: 80765
Because lst
is a value, not a function.
In F#, the technical difference between a value and a function is that a function has parameters, and a value does not.
When you declared lst
, you didn't give it any parameters, so the compiler understood it as "I want to take the value of accounts
at this particular point in time, and refer to that value as lst
from now on". So every time you write lst
, you're not calling a function, but merely referring to that same empty list that was the value of accounts
at initialization time.
To make lst
a true function, you need to give it a parameter. And because it doesn't really need any actual data, the natural parameter to give it is the unit
value - ()
.
let lst () = accounts
P.S. This whole trickiness ultimately comes from mutating state. Try to avoid it when possible.
Upvotes: 7
Reputation: 6537
Because lst
is a value not a function. You need to convert it to a function:
let lst () =
accounts
then you can call it by:
Accounts.lst()
Upvotes: 4