Zip

Hamming
Hamming in F#
module Hamming

let distance (strand1: string) (strand2: string): int option =
    if strand1.Length <> strand2.Length then
        None
    else
        Seq.zip strand1 strand2
        |> Seq.filter (fun (letter1, letter2) -> letter1 <> letter2)
        |> Seq.length
        |> Some

Error path

We start by checking if the strings have unequal lengths, and return None if so:

if strand1.Length <> strand2.Length then
    None
Note

Note that we're using string class' Length property, not a function like Seq.length. Even though F# is a functional-first language, you'll use types (like the string class) defined in the .NET framework, which is an object-oriented framework. Inevitably, you'll thus use objects that have methods and properties defined on them. Don't worry about using methods and objects though, F# is a multi-paradigm language and embraces the interaction with object-oriented code (like the string class).

Happy path

In the happy path, we know that the strings have the same length. We're using this in our call to Seq.zip:

Seq.zip strand1 strand2

What Seq.zip does is it takes two sequences and returns a sequence of (tuple) pairs, with the first pair containing the first element of the first sequence and the first element of the second sequence, and so on. We can use this to create letter pairs, as a string can be treated like a char sequence:

Seq.zip "GAG" "CAT"

is equivalent to:

seq { ('G', 'C'); ('A', 'A'); ('G', 'T') }

The next step is to select only those pairs where the letters are different, we se do by piping the zipped sequence to Seq.filter:

|> Seq.filter (fun (letter1, letter2) -> letter1 <> letter2)

With that, we now have a sequence of pairs with different letters. As the hamming distance is the number of different letter pairs, we can calculate the distance by counting the letter pairs using Seq.length and wrapping the count in a Some value:

|> Seq.length
|> Some
15th Sep 2024 · Found it useful?