Skip to content

Instantly share code, notes, and snippets.

@cameronpresley
Last active May 18, 2020 01:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cameronpresley/45dfdcb1bf4edf1d61539adb8a8170bf to your computer and use it in GitHub Desktop.
Save cameronpresley/45dfdcb1bf4edf1d61539adb8a8170bf to your computer and use it in GitHub Desktop.
Mars Rover - Modeling Concepts
public enum Command
{
MoveForward, MoveBackward,
TurnLeft, TurnRight,
Quit
}
type Command = MoveForward | MoveBackward
| TurnLeft | TurnRight | Quit
public class Address
{
public int HouseNumber {get; set;}
public string StreetName {get; set;}
public State State {get; set;}
}
type Address = {
houseNumber:int,
streetName:string,
state:State
}
public class Coordinate
{
public int X {get; set;}
public int Y {get; set;}
}
type Coordinate = {x:int; y:int}
public enum Direction
{
North, South, East, West
}
type Direction = North | East | South | West
public enum State
{
Alabama, Alaska, California, Delaware,
Florida, Georgia, Tennessee, Wyoming
}
public enum Suit
{
Hearts, Clubs, Spades, Diamonds
}
public enum Months
{
January, February, March, April, May, June,
July, August, September, October, November, December
}
type State = Alabama | Alaska | California
| Delaware | Florida | Georgia
| Tennesee | Wyoming
// If the value isn't a major component of the design, we can use a primitive type
int houseNumber;
// However, if the type is a major concept to the domain at hand,
// it makes sense to lift it to its own type
public class HouseNumber
{
public int Value {get;}
public StreetNumber(int input)
{
// validation logic
Value = input;
}
}
// The difference between the two approaches is that in the first case, this would work
int houseNumber = 400;
Math.Sqrt(houseNumber);
// But this wouldn't
var houseNumber = new HouseNumber(400);
Math.Sqrt(houseNumber); // fails to compile with "cannot convert from HouseNumber to double"
// If the value isn't a major component of the design, we can use a primitive type
let houseNumber:int;
// However, if the type is a major concept to the domain at hand,
// it makes sense to lift it to its own type (single case sum type)
type HouseNumber = HouseNumber of int
// The difference between the two approaches is that in the first case, this would work
let houseNumber = 400;
Math.Sqrt(houseNumber);
// But this wouldn't
let houseNumber = HouseNumber 400
Math.Sqrt(houseNumber); // fails to compile with
// "This expression was expected to have type 'float' but here has type 'HouseNumber'"
public class Rover
{
public Direction Orientation {get; set;}
public Coordinate Location {get; set;}
}
type Rover = {
orientation:Direction;
location:Coordinate;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment