My Brainfuck interpreter in F# I'm very new to functional world. I've written a simple brainfuck interpreter as my first F# program.

What I would like to know:


Am I using the right data structure for each situation?
Is my code easy to understand?
Is my code style similar to common F# codes (naming, organization etc)?
Is my code "very declarative" or I'm still thinking in the imperative way?


What is not so relevant:


Performance (but if I've made something very bad, let me now!)
More features


Obs.: I assume input is always a valid brainfuck code and that's ok to me.

open System
open System.IO

let getValue (position:int) (memory:Map&lt;int, int&gt;) =
    match Map.tryFind position memory with
    | None  -&gt; 0
    | value -&gt; value.Value

let calcAccumulator (acc:int) (instruction:char) (search:char) (miss:char) =
    match instruction with
    | x when x = search -&gt; acc+1
    | x when x = miss   -&gt; acc-1
    | _ -&gt; acc

let rec findMatch (code:string) (search:char) (miss:char) (inc:int) (current:int) (acc:int) =
    let instruction = code.[current]

    match instruction, acc with
    | x, 0 when x = search -&gt; current+1
    | _    -&gt; findMatch code search miss inc (current+inc) (calcAccumulator acc instruction search miss)

let updateMemory (instruction:char) (position:int) (memory:Map&lt;int, int&gt;) =
    let oldValue = getValue position memory
    let newValue =
        match instruction with
        | '+' -&gt; oldValue + 1
        | '-' -&gt; oldValue - 1
        | ',' -&gt; Console.ReadKey().KeyChar |&gt; Convert.ToInt32
        | _   -&gt; oldValue

    Map.add position newValue memory

let updateOutput (instruction) (value:int) =
    if instruction = '.'
    then Console.Write ((char) value)

let updatePosition (instruction:char) (position:int) =
    match instruction with
    | '&gt;' -&gt; position+1
    | '&lt;' -&gt; position-1
    | _   -&gt; position

let updateIndex (code:string) (index:int) (value:int) =
    match code.[index], value with
    | '[', 0 -&gt; findMatch code ']' '[' 1 (index+1) 0
    | ']', x when x &lt;&gt; 0 -&gt; findMatch code '[' ']' -1 (index-1) 0
    | _      -&gt; index+1

let rec interpretHelper (code:string) (index:int) (memory:Map&lt;int, int&gt;) (position:int) =
    match code.Length with
    | x when x = index  -&gt; memory
    | _ -&gt;
        let instruction = code.[index]
        let newPosition = updatePosition instruction position
        let newMemory = updateMemory instruction position memory
        let newIndex = updateIndex code index (getValue position memory)
        updateOutput instruction (getValue position memory)
        interpretHelper code newIndex newMemory newPosition

let interpret (code:string) =
    interpretHelper code 0 Map.empty 0

let options (args:string array) =
    let pathToFile = args.[0]
    let showMemory = 
        match args with
        | [| _ ; "-memory" |] -&gt; true
        | _                   -&gt; false

    pathToFile, showMemory

let onlyCode (text:string) =
    let validInstructions = "+-.,][&lt;&gt;".ToCharArray()

    String.filter (fun x -&gt; Array.contains x validInstructions) text

[&lt;EntryPoint&gt;]
let main args =
    let pathToFile, showMemory = options args
    let code = onlyCode (IO.File.ReadAllText pathToFile)
    let memory = interpret code

    if showMemory
    then Map.iter (fun a b -&gt; printf "\n%3d: %d" a b) memory

    0
Let me make a few comments:


F# has a good system of type inference. You don't need to specify the type explicitly, the compiler in many cases will do it for you. You can read more about it here.
In function getValue. Usually, matched with None|Some value:

match Map.tryFind position memory with
    | None  -&gt; 0
    | Some value -&gt; value


Although you can rewrite this code with using defaultArg

let getValue position memory =
    defaultArg (Map.tryFind position memory) 0 

In function updateIndex you can check the value with 0 in match:

let updateIndex (code:string) index value =
    match code.[index], value = 0 with
    | '[', true  -&gt; findMatch code ']' '['  1 (index + 1) 0
    | ']', false -&gt; findMatch code '[' ']' -1 (index - 1) 0
    | _      -&gt; index + 1

The helper functions better write as nested: 

let interpret (code:string) =
    let rec interpretHelper index memory position =


You can read more about it here
In function interpretHelper, use if-then-else instead of PM:

let rec interpretHelper index memory position =
    if code |&gt; String.length = index  then
        memory
    else ...