F# Referencing Types - f#

I am working on a project where the F# code will be consumed by other .NET projects - so I am using classes. I created a code file like this:
namespace StockApplication
open System
type Stock =
{Symbol: String;
DayOpen: Decimal;
Price: Decimal;
}
member x.GetChange () =
x.Price - x.DayOpen
member x.GetPercentChange() =
Math.Round(x.GetChange()/x.DayOpen,4)
This works fine when I consume it from some unit tests written in C#. For example:
[TestMethod]
public void CreateStock_ReturnsValidInstance()
{
Stock stock = new Stock("TEST", 10, 10.25M);
Assert.IsNotNull(stock);
}
I then went to create another file with another class. This class uses the 1st class so I made sure it was below the original class in VS2012. When I created the next class, I can see it available via intellisense.
namespace StockApplication
open System
type StockTicker() =
member x.GetStock () =
StockApplication.Stock
However, every attept to either new it or refer it gives me the same error:
Error 1 The value, constructor, namespace or type 'Stock' is not
defined
Does anyone have any insight on why I can just simply new up a class that I created in F# in another F# file?
Thanks in advance.

Your C# test having Stock stock = new Stock("TEST", 10, 10.25M); that was compiled without a problem prompts to believe that F# constructor for the Stock should look the same. But this is not true and, perhaps, was the source of your confusion.
Your original
type Stock =
{Symbol: String;
DayOpen: Decimal;
Price: Decimal; }
is of F# type Record indeed, not an ordinary class. The following excerpt from MSDN applies:
Record construction also differs from class construction. In a record type, you cannot define a constructor.
Meaning that
let stock = Stock("ABC"; 10M; 10M)
will produce error FS0039: The value or constructor 'Stock' is not defined while
let stock = { Symbol = "ABC"; DayOpen = 10M; Price = 10M; }
will successfully create a record instance.
In order to build an instance of type Stock in your second F# type StockTicker you should use record construction syntax, something like
member x.GetStock () = { Symbol = "MSFT"; DayOpen = 32M; Price = 32.5M; }
which compiles without any problems.
When it comes to interop use of F# record from C# the latter follows the syntax that you applied in your test method.

OK, after digging into this reference (MSDN was 0 help) here, I found the answer.
Here is the syntax for the Stock class:
namespace StockApplication
open System
type Stock = class
val Symbol: String
val DayOpen: Decimal
val Price: Decimal
new (symbol, dayOpen, price) =
{
Symbol = symbol;
DayOpen = dayOpen;
Price = price
}
member x.GetChange () =
x.Price - x.DayOpen
member x.GetPercentChange() =
Math.Round(x.GetChange()/x.DayOpen,4)
end
And here is the syntax for the consuming class:
namespace StockApplication
type StockTicker() =
member x.GetStock () =
let y = new Stock("AET",1m,1m)
y.DayOpen

Related

How to shadow a record in F# Program.fs?

I'm following the F# book Get Programming with F# and got to the part about shadowing. The simplest example they provide doesn't seem to be possible, so I'm wondering if either this syntax was removed or changed for F# 6 shadowing? I haven't been able to find anything stating that or how to do what the book offers as shadowing a record.
type Address =
{ Street: string
Town: string
City: string }
let home = { Street = "123 Main Street"; Town = "The Town"; City = "The City" }
let home = { home with City = "Second City" }
let home = { home with City = "Third City" }
When trying to build get an error stating: Duplicate definition of value 'home'
Edit
So after searching for answers without success as to why this doesn't work I tried putting the above into a function like so:
let testFunction =
let home = { Street = "123 Main Street"; Town = "The Town"; City = "The City" }
let home = { home with City = "Second City" }
let home = { home with City = "Third City" }
0
and it worked just fine. So my question now is why does shadowing work within a function but not outside? Is there a conflict with scoping on a module level that doesn't happen within a function's scope?
To add some more detail to the existing answers, there are four different cases.
Local definitions. If you are inside a function body, you can use shadowing and this is quite useful when doing a computation in multiple steps:
let adjust index =
let index = max 0 index
let index = min 100 index
index
Local definitions inside class. You are similarly allowed to shadow local definitions inside a class:
type A() =
let foo = 1
let foo = 2
member x.Foo = foo
Top-level in a script file. If you are at the top level in a script file (something.fsx) then you are allowed shadowing. The idea with script files is that they would be run manually, so it is useful to have multiple different versions - you just run the one you want by hand:
let test = calculation1 ()
let test = caluclation2 ()
Top-level in a module (source file). The only case where shadowing does not work is when you are in a module (or .fs file which becomes a module implicitly). In a module, definitions are public and they are compiled as static members of a class, so there is also a technical limitation (you cannot have multiple class members of the same name).
module Constants =
let answer = 1
let answer = 42 // error FS0037: Duplicate definition of value
Why shadowing is limited to function body?
There are probably some technical reasons. But the core reasons are IMO:
Naming is hard. Shadowing eases the pain but it can be confusing.
Also F# supports "tick naming" (home') to have a similar but different name. It's a kind of safer shadowing.

how to I create a Luau type that contains a key that requires quoting?

I'd like to be able to create a type that has a field invalid characters in it. With a table, I can do this:
local Element = {
["$$typeof"] = 31337,
}
with Roblox Luau types, I can't do this:
type Element = {
["$$typeof"]: number,
}
How can I strongly type that field of my Element table, without resorting to use of any?
As of March 2022, you can do this in Roblox Lua and in the open-source Luau parser and runtime v0.523 or later.
Element.lua
--!strict
export type Element = {
["$$typeof"]: number,
render: (self: Element, x: number, y: number) -> ()
}
local myElement: Element = {
["$$typeof"] = 31337,
render = function(self, a, b) end
}
Note that:
The source file requiring Element.lua doesn't have to be strict-mode enabled, but if you want type checking on the consumption of these strong types, you should favor strict mode, whenever practical, across all your source files.

Add an "abstract" method to (an F#) record

I have created the following record in an attempt to translate a C# class to F#:
type Days = Days of int
type Value = Value of int
type Item = {
Name: string
Expires: Days
Value: Value
}
Thing is I also need every Item to have a... "way", to run another function, yet not defined, handleDevalue, which acts on the item itself to manipulate the item's Value value.
The handleDevalue function is dependent on the Expires property of the item and thus each item's implementation of it would be different, with the only common thread being the function's name and signature (Item -> Item).
On the C# code I'm translating this method was defined as abstract on the Item class and overriden on every item instantiated (where every item is a subclass inheriting from Item).
What I've tried, unsuccessfully till now:
Add an abstract method on the record: ...} with abstract handleDevalue: Item -> Item.
1.1 Reason for failure: IDE tells me "abstract can't be added here as an augmentation" (or something close to the same effect). (I'm not F#-savvy enough to even know what it means, but the compiler won't let it compile so... no).
Add handleDevalue as a function on the record: {... HandleDevalue: Item -> Item...}.
2.1. Reason for failure: this function is dependent on the Expires property. Apparently a record's fields are mutually independent of each other, and besides... how will the function "know" which item to act on (it's supposed to act on the item itself)? The this keyword is not allowed when implementing a function when "instantiating" a record (i.e. no {...handleDevalue = fun this -> <some implementation code here>).
I could remember to define the function on every item I create (I should anyway), but that's not using the type system to my advantage.
I want the compiler to force me to implement the function and remind me if I don't.
With these ways failing I'm out of ideas how to move forward.
Thanks for any advice in advance.
I'm not really sure what you are trying to accomplish here, but I'll give it a shot.
Why not do something similar to this, using a discriminated union instead of inheritance?
type Days = Days of int
type Value = Value of int
type Item = {
name: string
expires: Days
value: Value
}
type ItemType =
| FooItem of Item
| BarItem of Item
| BazItem of Item
// ...
let deValue item =
match item with
| FooItem i ->
{
name = i.name
expires = i.expires -1
value = i.value -1
} |> FooItem
| BarItem i ->
{
name = i.name
expires = i.expires -1
value = i.value -10
} |> BarItem
| // etc
Think about what actually happens in the C# program.
You have several different implementations of handleDevalue, and every item instance has one of those implementations associated with it. But what determines which one goes with which item? Well, this is determined by the specific descendant class that the item is. Ok, but what determines which descendant class gets instantiated?
Somewhere, at some point, there must be a place that picks a descendant class somehow. Let's assume it looks something like this:
class Item { public abstract int handleDevalue() { ... } }
class FooItem : Item { public override int handleDevalue() { ... } }
class BarItem : Item { public override int handleDevalue() { ... } }
public Item createItem(string name, Days expires, Value value) {
if (foo) return new FooItem(name, expires, value)
else return BarItem(name, expires, value)
}
So, look what's happening: ultimately, whoever creates the items is choosing which handleDevalue implementation ends up being used, and then that implementation gets attached to the item instance via the method table.
Now that we know this, we can do the same thing in F#. We'd just need to make attaching of the implementation explicit:
type Item = {
Name : string
Expires : Days
Value : Value
handleDevalue : Item -> Item
}
let handleDevalueFoo item = ...
let handleDevalueBar item = ...
let createItem name expires value = {
Name = name
Expires = expires
Value = value
handleDevalue = if foo then handleDevalueFoo else handleDevalueBar
}

TypeError while attempting to sort a list of custom objects

I'm new to Dart and tried to get a class to implement List using the answers here, and tried to sort a list of these objects using the docs here. I deleted most of my code in an effort to post a MWE:
import 'dart:collection';
class Transaction<E> extends ListBase<E>{
DateTime when;
Transaction(this.when);
List innerList = new List();
int get length => innerList.length;
void set length(int length){
innerList.length = length;
}
void operator[]=(int index, E value){
innerList[index] = value;
}
E operator [](int index) => innerList[index];
void add(E value) => innerList.add(value);
void addAll(Iterable<E> all) => innerList.addAll(all);
}
class Forecaster{
var transactions;
Forecaster(){
this.transactions = new List<dynamic>();
}
void tabulate(){
transactions.sort((a,b) => a.when.compareTo(b.when)); //problem line?
for(var d in transactions){
d.asMap().forEach((index,content){
int len = content.toStringAsFixed(2).length;
});
}
}
void forecast(var forWhen){
var first = new Transaction(DateTime.now());
first.addAll([5,9]);
transactions.add(first);
}
}
void main(){
Forecaster myTest = new Forecaster();
var dub = myTest;
dub..forecast(DateTime.now())
..tabulate();
}
Running with the problem line results in an exception (Uncaught exception: TypeError: Closure 'Forecaster_tabulate_closure': type '(dynamic, dynamic) => dynamic' is not a subtype of type '(dynamic, dynamic) => int') I don't understand. If I comment out the problem line, the TypeError goes away. Is the TypeError because I did something wrong when defining Transaction? I'm attempting this with DartPad.
I'm new to Dart too, so my explanation might not be 100% on the money, but I believe, yes, the main issue is the type assignment of transactions. I think because you initialize it as a var, it is having trouble deducing the type of a.when, which is means it also doesn't know the type of a.when.compareTo(), and assumes dynamic. You are feeding the output of compareTo into List.sort() which is expecting an int from the anonymous function. Thus the error that it wanted an int but got dynamic.
The easiest way to address this is to initialize transactions with a more explicit type rather than as var:
List<Transaction> transactions;
Forecaster(){
this.transactions = new List<Transaction>();
}
Also, to confirm that it is an issue with it not being able to infer the return type of compareTo, I tried leaving your code as-is, but explicitly casting the result as int, and that also worked:
transactions.sort((a,b){
return (a.when.compareTo(b.when) as int);
});
Note: code like the above and using lots of dynamics and vars is in general not great practice with Dart - you lose a lot of the benefits of having a typed language. You might also notice that when you type in an IDE, you don't get methods auto-suggested when you do stuff like this - for example, until I changed transactions to an explicit type of list, typing a.when did not trigger autocomplete, and my IDE thought the type was dynamic, not DateTime.
Your problem is with the types. The code:
var transactions;
Forecaster(){
this.transactions = new List<dynamic>();
}
void tabulate(){
transactions.sort((a,b) => a.when.compareTo(b.when));
first declares transactions to have type dynamic.
Then you call sort on that with an argument which is inferred to have type dynamic Function(dynamic, dynamic) (because there is no clue available to say otherwise in the type of transactions).
However, the actual run-time type of transactions is List<Transaction>, and that requires a function argument of type int Function(Transaction, Transaction). The type dynamic Function(dynamic, dynamic) is not a sub-type of int Function(Transaction, Transaction) (the return type has to be a subtype of int for that to be the case) so you get a run-time error.
If you change transactions to have type List<Transaction>, then the type inference will have a clue when it gets to the function literal. It will infer that (a, b) => a.when.compareTo(b.when) in a context expecting int Function(Transaction, Transaction) will have that type.
Even if you just change transactions to List<dynamic>, it will still work, it will just make a.when.compareTo(b.when) be dynamic invocations.

Modeling database records as types

I'm rewriting a C# library in F# in which most of the classes map one-to-one with database tables (similar to ActiveRecord). I'm considering whether to use records or classes (maybe even DUs?). There's a fair amount of validation in the property setters to maintain invariants. What would be the best way to model this in F#? I don't want an object that violates business logic to be persisted to the database. Any ideas are welcome.
A few additional thoughts...
Is it better to move the invariants to an external 'controller' class? Coming from C# it feels wrong to allow an object that corresponds to a database record to contain anything that can't be saved to the database. I suppose because failing earlier seems better than failing later.
You can have your data in a record, and still keep the validation logic with the data type, by attaching methods to the record:
type Person =
{ First : string;
Last : string; } with
member x.IsValid () =
let hasValue = System.String.IsNullOrEmpty >> not
hasValue x.First && hasValue x.Last
let jeff = { First = "Jeff"; Last = "Goldblum" }
let jerry = { jeff with First = "Jerry" }
let broken = { jerry with Last = "" }
let valid = [jeff; jerry; broken]
|> List.filter (fun x -> x.IsValid())
The copy semantics for records are almost as convenient as setting a property. The validation doesn't happen on property set, but it's easy to filter a list of records down to only the valid ones.
This should actually be a good way for you to handle it. Having your validation logic in the constructor will give you piece of mind later on in your code because the object is immutable. This also opens up multi-threading possibilities.
Immutable Version
type Customer (id, name) =
do // Constructor
if id <= 0 then
raise(new ArgumentException("Invalid ID.", "id"))
elif String.IsNullOrEmpty(name) then
raise(new ArgumentException("Invalid Name.", "name"))
member this.ID
with get() = id
member this.Name
with get() = name
member this.ModifyName value =
new Customer(id, value)
Mutable Version
type Customer (id) =
let mutable name = ""
do // Constructor
if id <= 0 then
raise(new ArgumentException("Invalid ID.", "id"))
member this.ID
with get() = id
member this.Name
with get() = name
and set value =
if String.IsNullOrEmpty(name) then
raise(new ArgumentException("Invalid Name.", "value"))
name <- value
Have you taken a look at my FunctionalNHibernate project? It's designed as a layer on top of nhibernate to let you declaratively map records to a database. It's early days, but it's just about usable:
http://bitbucket.org/robertpi/functionalnhibernate/

Resources