Rewriting C# implementation of Snake class in F#
There are a few small differences in your translation. I would start with as literal a translation possible, then optimize/make idiomatic from there. If done incrementally it should be easy to spot performance problems as they occur. Here's a starting point:

(* stub *)
[&lt;AllowNullLiteral&gt;]
type Symbol =
  member x.Payout = [|0|]
  member x.Type = 0
  static member Add(sym1, sym2) : Symbol = null

(* stub *)
type Apple =
  abstract MySymbol : Symbol
  abstract Multiplier : int

type private BestSnake =
  | This
  | RecentSnake of Snake

and [&lt;AllowNullLiteral&gt;] Snake private (mySymbol: Symbol, multiplier, hit, bestSnake) as this =
  let payout = mySymbol.Payout.[hit - 1] * (match multiplier with 0 -&gt; 1 | m -&gt; m)
  let bestSnake =
    match bestSnake with
    | This -&gt; this
    | RecentSnake bestRecentSnake -&gt;
      if payout &lt; bestRecentSnake.Payout || 
        (payout = bestRecentSnake.Payout &amp;&amp; bestRecentSnake.MySymbol.Type = 1 &amp;&amp; mySymbol.Type &lt;&gt; 1) 
      then bestRecentSnake
      else null

  member val MySymbol : Symbol = mySymbol
  member val Multiplier = multiplier
  member val Hit = hit
  member val BestSnake = bestSnake
  member val Payout = payout

  new (mySymbol, multiplier, hit, bestRecentSnake) = Snake(mySymbol, multiplier, hit, RecentSnake bestRecentSnake)
  new (mySymbol, multiplier, hit) = Snake(mySymbol, multiplier, hit, This)
  new (myApple: Apple) = Snake(myApple.MySymbol, myApple.Multiplier, 1, This)

  member this.Eat(nextApple: Apple) =
    match Symbol.Add(this.MySymbol, nextApple.MySymbol) with
    | null -&gt; null
    | resultSymbol -&gt; Snake(resultSymbol, max this.Multiplier nextApple.Multiplier, this.Hit + 1, this.BestSnake)


The performance of this should be on par with C#.