As @ s952163 points out, it looks like you're trying to read data from a database, in which case there are better options than trying to do it yourself. However, just to outline a possible solution, if you take the OP at face value, here is one way to do this.
Since the types listed are not .NET types, it might be better to define a native type to store these values:
open System type DbType = NVarChar of string | DT of DateTime
You can add a few cases to DbType if you want.
Using active templates , you can write a function to convert a single candidate:
// string * string -> string option let (|NVarChar|_|) = function | "nvarchar", (x : string) -> Some x | _ -> None // string * string -> DateTime option let (|DT|_|) (typeHint, value) = match (typeHint, DateTime.TryParse value) with | "date", (true, dt) -> Some dt | _ -> None // string * string -> DbType option let convertPair = function | NVarChar x -> Some (NVarChar x) | DT x -> Some (DT x) | _ -> None
Using active templates is not strictly necessary, but I thought that it allowed me to efficiently decompose the problem.
Now you can declare a list of types and one of the values, pin them together to get a list of interpreted values:
> let types = ["nvarchar"; "nvarchar"; "date"; "nvarchar"];; val types : string list = ["nvarchar"; "nvarchar"; "date"; "nvarchar"] > let values = ["Jackson"; "Sentzke"; "1991-04-19T00:00:00"; "Jackson Sentske"];; val values : string list = ["Jackson"; "Sentzke"; "1991-04-19T00:00:00"; "Jackson Sentske"] > let converted = List.zip types values |> List.choose convertPair;; val converted : DbType list = [NVarChar "Jackson"; NVarChar "Sentzke"; DT 19.04.1991 00:00:00; NVarChar "Jackson Sentske"]
Note that both types and values are of type string list . In the OP they were (string * string * string * string) list , which I suppose was a mistake.