Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting C# struct to F#

Tags:

c#

f#

I have code like this in C#:

namespace WumpusWorld
    {
        class PlayerAI
        {
            //struct that simulates a cell in the AI replication of World Grid
            struct cellCharacteristics
            {
                public int pitPercentage;
                public int wumpusPercentage;
                public bool isPit;
                public bool neighborsMarked;
                public int numTimesvisited;
            }

            private cellCharacteristics[,] AIGrid;                    //array that simulates World Grid for the AI
            private enum Move { Up, Down, Right, Left, Enter, Escape };   //enum that represents integers that trigger movement in WumpusWorldForm class
            Stack<int> returnPath;                                      //keeps track of each move of AI to trace its path back
            bool returntoBeg;                                           //flag that is triggered when AI finds gold
            int numRandomMoves;                                         //keeps track of the number of random moves that are done

            public PlayerAI()
            {
                AIGrid = new cellCharacteristics[5, 5];
                cellCharacteristics c;
                returntoBeg = false;
                returnPath = new Stack<int>();
                numRandomMoves = 0;

                for (int y = 0; y < 5; y++)
                {
                    for (int x = 0; x < 5; x++)
                    {
                        c = new cellCharacteristics();
                        c.isPit = false;
                        c.neighborsMarked = false;
                        c.numTimesvisited = 0;

                        AIGrid[x, y] = c;
                    }
                }
            }
        }
    }

I don't know how to convert this C# struct to F# and implement the struct into an array like my code above.

like image 375
Yabert Yanuar Avatar asked Nov 14 '11 14:11

Yabert Yanuar


1 Answers

You can define a struct either using the struct keyword (as shown by Stilgar) or using the Struct attribute, which looks like this. I also added a constructor that initializes the structure:

[<Struct>]
type CellCharacteristics =
  val mutable p : int
  val mutable w : int
  val mutable i : bool
  val mutable ne : bool
  val mutable nu : int

  new(_p,_w,_i,_ne,_nu) = 
    { p = _p; w = _w; i = _i; ne = _ne; nu = _nu }

// This is how you create an array of structures and mutate it
let arr = [| CellCharacteristics(1,2,true,false,3) |]
arr.[0].nu <- 42 // Fields are public by default

However, it is generally not recommended to use mutable value types. This causes confusing behavior and the code is quite difficult to reason about. This is discouraged not just in F#, but even in C# and .NET in general. In F#, creating an immutable struct is also easier:

// The fields of the strcuct are specified as part of the constructor
// and are stored in automatically created (private) fileds
[<Struct>]
type CellCharacteristics(p:int, w:int, i:bool, ne:bool, nu:int) =
  // Expose fields as properties with a getter
  member x.P = p
  member x.W = w
  member x.I = i
  member x.Ne = ne
  member x.Nu = nu

When using immutable structs, you won't be able to modify individual fields of the struct. You'll need to replace the entire struct value in the array instead. You can typically implement calculation as a member of the struct (say Foo) and then just write arr.[0] <- arr.[0].Foo() to perform the update.

like image 120
Tomas Petricek Avatar answered Sep 18 '22 18:09

Tomas Petricek