`lookup`

is actually `assoc`

, in F# included in the module `List`

. So how about trying a F# version similar to the Haskell one? Well, the problem is, as I mentioned, that F# doesn't have `zip`

, `take`

and `drop`

, and there is no way to map over a string. So we have to define all these functions, and then define `rot13`

as in the Haskell version. I defined `zipWith`

from the Haskell prelude as well, and then used it to define `zip`

(as it is in Haskell).

#light

let strmap f (s : string) =

let sb = new System.Text.StringBuilder(s)

let rec aux i =

if i = sb.Length then () else

(sb.Chars(i) <- f (sb.Chars(i)) ; aux (i + 1))

( aux 0; sb.ToString() )

let rec drop n l =

match (l, n) with

([], _) -> []

| (l, 0) -> l

| (_ :: rl, n) -> drop (n - 1) rl

let rec take n l =

match (l, n) with

([], _) -> []

| (l, 0) -> []

| (x :: rl, n) -> x :: (take (n - 1) rl)

let rec zipWith f l1 l2 =

match (l1, l2) with

([], _) -> []

| (_, []) -> []

| (x1 :: rl1, x2 :: rl2) -> (f x1 x2) :: (zipWith f rl1 rl2)

let zip l1 l2 =

zipWith (fun a b -> (a, b)) l1 l2

// and now for something completely different

let rot13 s =

let letters = ['a' .. 'z']

let transp = zip letters ((drop 13 letters) @ (take 13 letters))

let rotchar c = List.assoc c transp

strmap rotchar s

Works as expected, but we ended with code that is still longer than the first version, only because it was necessary to define some general-use functions. I guess I will create a Prelude module to use with F#, containing the Haskell functions I use most.

## No comments:

Post a Comment