Cassandra CQL Mapping in F# - f#

I am having a problem trying to map a property on my type to a mapping in Cassandra.
I have it working in C#, but i am struggling with the F#
The error i get is: Stack Trace: [System.ArgumentOutOfRangeException: Expression x => new Tuple`2(x.Id, ToFSharpFunc(x => x.WithName("player_id"))) is not a property or field. Parameter name: expression]
on Line 26, if I removed "fun(x:ColumnMap)->x.WithName("player_id")" it compiles but then it will not map to the correct table column. My models property name is "Id" but i need it to map to "player_id"
open Cassandra
open Cassandra.Mapping
open System
type Ranking =
{ Id : Guid
Alias : string
Kills : int
Deaths : int }
type Player = {Id: Guid; Alias: string; Dob: DateTime; FullName: string}
type CassyMappings() =
inherit Cassandra.Mapping.Mappings()
do
base.For<Player>()
.TableName("players")
.PartitionKey("player_id")
.Column(fun(x:Player)-> x.Id)
.Column(fun(x:Player)-> x.Alias)
.Column(fun(x:Player)-> x.FullName)
.Column(fun(x:Player)-> x.Dob) |> ignore
base.For<Ranking>()
.TableName("rankings")
.PartitionKey("player_id")
.Column(fun (x : Ranking) -> x.Id, fun(x:ColumnMap)->x.WithName("player_id"))
.Column(fun (x : Ranking) -> x.Alias)
.Column(fun (x : Ranking) -> x.Kills)
.Column(fun (x : Ranking) -> x.Deaths) |> ignore
MappingConfiguration.Global.Define<CassyMappings>()
printfn "Works fine!"
https://dotnetfiddle.net/8IiYhg
here is a link to the C# http://www.datastax.com/dev/blog/csharp-driver-cassandra-new-mapper-linq-improvements

You're missing parentheses.
The expression on line 26 is getting compiled as:
.Column(fun (x : Ranking) -> (x.Id, fun(x:ColumnMap)->x.WithName("player_id")) )
That is, as an expression that takes a Ranking as parameter and produces a tuple of int and a function as result. Just to be more clear, here's a more expanded version of the same code:
.Column(
fun (x : Ranking) ->
let id = x.Id
let f = fun (x:ColumnMap)->x.WithName("player_id")
id, f )
The result of such expression is a Tuple<_,_>, and CQL interpreter expects a plain property access instead, and this is exactly what it tells you in the error message.
But what you really (apparently) intended to do was to call a different overload of .Column, which takes two parameters, one expression and one function. To prevent the compiler from considering the second function a part of the previous function's body, you just need to add parentheses around both functions:
.Column(
(fun (x : Ranking) -> x.Id),
(fun (x:ColumnMap)->x.WithName("player_id")) )
Or to put it on one line:
.Column( (fun (x : Ranking) -> x.Id), (fun (x:ColumnMap)->x.WithName("player_id")) )

Related

What those F# functions are supposed to do?

Learning F# these days, I've noticed that in some libraries like this one or that one
there are some similar functions which seem to be common in F# but can't really decipher them, what are they doing, what are they for?
let ap x f =
match f, x with
| Ok f , Ok x -> Ok (f x)
| Error e , _ -> Error e
| _ , Error e -> Error e
let inline (<*>) f x = ap x f
let inline (<!>) f x = Result.map f x
let inline lift2 f a b = f <!> a <*> b
Even aggregating comments with them does not really help in my understanding:
/// Sequential application
/// If the wrapped function is a success and the given result is a success the function is applied on the value.
/// Otherwise the exisiting error messages are propagated.
let ap x f =
match f,x with
| Ok f , Ok x -> Ok (f x)
| Error e , _ -> Error e
| _ , Error e -> Error e
/// Sequential application
/// If the wrapped function is a success and the given result is a success the function is applied on the value.
/// Otherwise the exisiting error messages are propagated.
let inline (<*>) f x = ap x f
/// Infix map, lifts a function into a Result and applies it on the given result.
let inline (<!>) f x = Result.map f x
/// Promote a function to a monad/applicative, scanning the monadic/applicative arguments from left to right.
let inline lift2 f a b = f <!> a <*> b
I don't even see an example of how they could be used, not sure also why inline has been used.
If there is somebody who could hint about how useful those functions are, I would greatly appreciate.
These are called "applicative functors" (sometimes just "applicatives"). Their purpose is to combine data from multiple Something<'T> using a function. Basically, "lifting" a function of type 'Arg1 -> 'Arg2 -> ... -> 'Result into a function of type Something<'Arg1> -> Something<'Arg2> -> ... -> Something<'Result>.
For example, given the standard Result type:
type Result<'T, 'Err> = Ok of 'T | Error of 'Err
you may have several Result values that you want to combine together. For example, say you have a form with inputs firstName, lastName and age. You also have a result type Person:
type Person = { firstName: string; lastName: string; age: int }
// string -> string -> int -> Person
let makePerson firstName lastName age =
{ firstName = firstName; lastName = lastName; age = age }
The values coming from your actual form may have type Result<string, InputError> or Result<int, InputError>, which can be Error if eg. the user hasn't entered a value.
type InputError =
| FieldMissing of fieldName: string
// Other error cases...
You want to combine them into a Result<Person, InputError>, which is Ok if all inputs are Ok, or Error if any input is Error. Using the applicative, you can do it like this:
// Result<string, InputError> -> Result<string, InputError> -> Result<int, InputError> -> Result<Person, InputError>
let makePersonResult firstName lastName age =
makePerson <!> firstName <*> lastName <*> age
// Example uses:
makePersonResult (Ok "John") (Ok "Doe") (Ok 42)
// --> Ok { firstName = "John"; lastName = "Doe"; age = 42 }
makePersonResult (Error (FieldMissing "firstName")) (Ok "Doe") (Ok 42)
// --> Error (FieldMissing "firstName")
A similar concept can be applied to many other types than Result, which is why it was given a name. For example, an applicative on Async<'T> could run all the argument Asyncs in parallel, and when they're finished, combine their results into an Async<'Result>. Another example, an applicative on 'T list would be equivalent to the standard library's List.map2 or List.map3 but generalizable to any number of argument lists.
Side note: if you look up "applicative functor", most of the results you'll find will be in Haskell, where the map operator, usually written <!> in F#, is written <$> instead.
Scott Wlaschin's F# for fun and profit (https://fsharpforfunandprofit.com) has a series Map and Bind and Apply, Oh my! (https://fsharpforfunandprofit.com/posts/elevated-world-7) which should be able to shed more light on this. Regarding your particular question:
<!> is the map operator which applies a function f and a parameter x to elements of the data structure you are mapping over, or in other words, lifts the function into the realm of the data structure, in this case the Result type.
<*> is the ap (apply) operator which unpacks a function wrapped inside a elevated value into a lifted function.
lift2 is basically the map operator for a two-parameter function.
Please have a look at the blog, it really helps!

type mismatch error for async chained operations

Previously had a very compact and comprehensive answer for my question.
I had it working for my custom type but now due to some reason I had to change it to string type which is now causing type mismatch errors.
module AsyncResult =
let bind (binder : 'a -> Async<Result<'b, 'c>>) (asyncFun : Async<Result<'a, 'c>>) : Async<Result<'b, 'c>> =
async {
let! result = asyncFun
match result with
| Error e -> return Error e
| Ok x -> return! binder x
}
let compose (f : 'a -> Async<Result<'b, 'e>>) (g : 'b -> Async<Result<'c, 'e>>) = fun x -> bind g (f x)
let (>>=) a f = bind f a
let (>=>) f g = compose f g
Railway Oriented functions
let create (json: string) : Async<Result<string, Error>> =
let url = "http://api.example.com"
let request = WebRequest.CreateHttp(Uri url)
request.Method <- "GET"
async {
try
// http call
return Ok "result"
with :? WebException as e ->
return Error {Code = 500; Message = "Internal Server Error"}
}
test
type mismatch error for the AsyncResult.bind line
let chain = create
>> AsyncResult.bind (fun (result: string) -> (async {return Ok "more results"}))
match chain "initial data" |> Async.RunSynchronously with
| Ok data -> Assert.IsTrue(true)
| Error error -> Assert.IsTrue(false)
Error details:
EntityTests.fs(101, 25): [FS0001] Type mismatch. Expecting a '(string -> string -> Async<Result<string,Error>>) -> 'a' but given a 'Async<Result<'b,'c>> -> Async<Result<'d,'c>>' The type 'string -> string -> Async<Result<string,Error>>' does not match the type 'Async<Result<'a,'b>>'.
EntityTests.fs(101, 25): [FS0001] Type mismatch. Expecting a '(string -> string -> Async<Result<string,Error>>) -> 'a' but given a 'Async<Result<string,'b>> -> Async<Result<string,'b>>' The type 'string -> string -> Async<Result<string,Error>>' does not match the type 'Async<Result<string,'a>>'.
Edit
Curried or partial application
In context of above example, is it the problem with curried functions? for instance if create function has this signature.
let create (token: string) (json: string) : Async<Result<string, Error>> =
and then later build chain with curried function
let chain = create "token" >> AsyncResult.bind (fun (result: string) -> (async {return Ok "more results"}))
Edit 2
Is there a problem with following case?
signature
let create (token: Token) (entityName: string) (entityType: string) (publicationId: string) : Async<Result<string, Error>> =
test
let chain = create token >> AsyncResult.bind ( fun (result: string) -> async {return Ok "more results"} )
match chain "test" "article" "pubid" |> Async.RunSynchronously with
Update: At the front of the answer, even, since your edit 2 changes everything.
In your edit 2, you have finally revealed your actual code, and your problem is very simple: you're misunderstanding how the types work in a curried F# function.
When your create function looked like let create (json: string) = ..., it was a function of one parameter. It took a string, and returned a result type (in this case, Async<Result<string, Error>>). So the function signature was string -> Async<Result<string, Error>>.
But the create function you've just shown us is a different type entirely. It takes four parameters (one Token and three strings), not one. That means its signature is:
Token -> string -> string -> string -> Async<Result<string, Error>>
Remember how currying works: any function of multiple parameters can be thought of as a series of functions of one parameter, which return the "next" function in that chain. E.g., let add3 a b c = a + b + c is of type int -> int -> int -> int; this means that add3 1 returns a function that's equivalent to let add2 b c = 1 + b + c. And so on.
Now, keeping currying in mind, look at your function type. When you pass a single Token value to it as you do in your example (where it's called as create token, you get a function of type:
string -> string -> string -> Async<Result<string, Error>>
This is a function that takes a string, which returns another function that takes a string, which returns a third function which takes a string and returns an Async<Result<whatever>>. Now compare that to the type of the binder parameter in your bind function:
(binder : 'a -> Async<Result<'b, 'c>>)
Here, 'a is string, so is 'b, and 'c is Error. So when the generic bind function is applied to your specific case, it's looking for a function of type string -> Async<Result<'b, 'c>>. But you're giving it a function of type string -> string -> string -> Async<Result<string, Error>>. Those two function types are not the same!
That's the fundamental cause of your type error. You're trying to apply a function that returns a function that returns function that returns a result of type X to a design pattern (the bind design pattern) that expects a function that returns a result of type X. What you need is the design pattern called apply. I have to leave quite soon so I don't have time to write you an explanation of how to use apply, but fortunately Scott Wlaschin has already written a good one. It covers a lot, not just "apply", but you'll find the details about apply in there as well. And that's the cause of your problem: you used bind when you needed to use apply.
Original answer follows:
I don't yet know for a fact what's causing your problem, but I have a suspicion. But first, I want to comment that the parameter names for your AsyncResult.bind are wrong. Here's what you wrote:
let bind (binder : 'a -> Async<Result<'b, 'c>>)
(asyncFun : Async<Result<'a, 'c>>) : Async<Result<'b, 'c>> =
(I moved the second parameter in line with the first parameter so it wouldn't scroll on Stack Overflow's smallish column size, but that would compile correctly if the types were right: since the two parameters are lined up vertically, F# would know that they are both belonging to the same "parent", in this case a function.)
Look at your second parameter. You've named it asyncFun, but there's no arrow in its type description. That's not a function, it's a value. A function would look like something -> somethingElse. You should name it something like asyncValue, not asyncFun. By naming it asyncFun, you're setting yourself up for confusion later.
Now for the answer to the question you asked. I think your problem is this line, where you've fallen afoul of the F# "offside rule":
let chain = create
>> AsyncResult.bind (fun (result: string) -> (async {return Ok "more results"}))
Note the position of the >> operator, which is to the left of its first operand. Yes, the F# syntax appears to allow that in most situations, but I suspect that if you simply change that function definition to the following, your code will work:
let chain =
create
>> AsyncResult.bind (fun (result: string) -> (async {return Ok "more results"}))
Or, better yet because it's good style to make the |> (and >>) operators line up with their first operand:
let chain =
create
>> AsyncResult.bind (fun (result: string) -> (async {return Ok "more results"}))
If you look carefully at the rules that Scott Wlaschin lays out in https://fsharpforfunandprofit.com/posts/fsharp-syntax/, you'll note that his examples where he shows exceptions to the "offside rule", he writes them like this:
let f g h = g // defines a new line at col 15
>> h // ">>" allowed to be outside the line
Note how the >> character is still to the right of the = in the function definition. I don't know exactly what the F# spec says about the combination of function definitions and the offside rule (Scott Wlaschin is great, but he's not the spec so he could be wrong, and I don't have time to look up the spec right now), but I've seen it do funny things that I didn't quite expect when I wrote functions with part of the function definition on the same line as the function, and the rest on the next line.
E.g., I once wrote something like this, which didn't work:
let f a = if a = 0 then
printfn "Zero"
else
printfn "Non-zero"
But then I changed it to this, which did work:
let f a =
if a = 0 then
printfn "Zero"
else
printfn "Non-zero"
I notice that in Snapshot's answer, he made your chain function be defined on a single line, and that worked for him. So I suspect that that's your problem.
Rule of thumb: If your function has anything after the = on the same line, make the function all on one line. If your function is going to be two lines, put nothing after the =. E.g.:
let f a b = a + b // This is fine
let g c d =
c * d // This is also fine
let h x y = x
+ y // This is asking for trouble
I would suspect that the error stems from a minor change in indentation since adding a single space to an FSharp program changes its meaning, the FSharp compiler than quickly reports phantom errors because it interprets the input differently. I just pasted it in and added bogus classes and removed some spaces and now it is working just fine.
module AsyncResult =
[<StructuralEquality; StructuralComparison>]
type Result<'T,'TError> =
| Ok of ResultValue:'T
| Error of ErrorValue:'TError
let bind (binder : 'a -> Async<Result<'b, 'c>>) (asyncFun : Async<Result<'a, 'c>>) : Async<Result<'b, 'c>> =
async {
let! result = asyncFun
match result with
| Error e -> return Error e
| Ok x -> return! binder x
}
let compose (f : 'a -> Async<Result<'b, 'e>>) (g : 'b -> Async<Result<'c, 'e>>) = fun x -> bind g (f x)
let (>>=) a f = bind f a
let (>=>) f g = compose f g
open AsyncResult
open System.Net
type Assert =
static member IsTrue (conditional:bool) = System.Diagnostics.Debug.Assert(conditional)
type Error = {Code:int; Message:string}
[<EntryPoint>]
let main args =
let create (json: string) : Async<Result<string, Error>> =
let url = "http://api.example.com"
let request = WebRequest.CreateHttp(Uri url)
request.Method <- "GET"
async {
try
// http call
return Ok "result"
with :? WebException as e ->
return Error {Code = 500; Message = "Internal Server Error"}
}
let chain = create >> AsyncResult.bind (fun (result: string) -> (async {return Ok "more results"}))
match chain "initial data" |> Async.RunSynchronously with
| Ok data -> Assert.IsTrue(true)
| Error error -> Assert.IsTrue(false)
0

How to interpret a function signature

I am still confused on how to read function signatures.
The Option.map signature is the following:
/// map f inp evaluates to match inp with None -> None | Some x -> Some (f x).
/// mapping: A function to apply to the option value.
/// option: The input option.
val map : mapping:('T -> 'U) -> option:'T option -> 'U option
However, I have no clue what that signature means.
I read it as the following:
There's a function called map that takes a function as an input that we'll call "mapping" and it will yield a result that is also a function that we'll call "option".
Mapping Parameter:
mapping:('T -> 'U)
The function that we pass in as input takes Titanium (i.e. 'T) as the input and yields Uranium (i.e. 'U) as output.
The Option returned
option:'T option -> 'U option
We'll call the output of the map function "option".
Thus, this "option" that is returned from executing the map function is also a function as referenced above. It's takes a Titanium option and yields a Uranium option.
Example:
type String20 = String20 of string
type Name = { First:String20
Last:String20
Suffix:String20 option }
let tryCreateName (first:string) (last:string) (suffix:string option) =
let isValid = [first; last]
|> List.forall (fun x -> x.Length > 2 && x.Length <= 20)
if isValid then
Some { First = String20(first);
Last = String20(last);
Suffix = Option.map String20 suffix }
else None
How does the following expression map:
Option.map String20 suffix
Based on the expression above, where is the "returned function" of Titanium option -> Uranium option?
First off take a look at Option.map<'T,'U> Function (F#) and notice
The expression map f inp evaluates to match inp with None -> None |
Some x -> Some (f x).
So lets convert this comment to working code. First map is a method of the type Option, but to make it easier we will make it a function outside of a type and to avoid conflicts with other map functions we will give it the name OptionMap.
let OptionMap = f inp =
match inp with
| None -> None
| Some x -> Some (f x)
Now to get the signature of this function just send it to F# Interactive
val OptionMap : f:('a -> 'b) -> inp:'a option -> 'b option
and to make the types obvious we will type the parameters of the function.
let optionMap (f : ('a -> 'b)) (inp : 'a option) : 'b option =
match inp with
| None -> None
| Some x -> Some (f x)
Now to test this we can use
let (test : String20 option) = optionMap String20 (Some("something"))
printfn "test: %A" test
// test: Some (String20 "something")
So what happened in OptionMap that allowed this to work
If we add some print statements let sees what happens
let optionMap (f : ('a -> 'b)) (inp : 'a option) : 'b option =
printfn "f: %A" f
printfn "inp: %A" inp
match inp with
| None -> None
| Some x ->
let result = Some (f x)
printfn "result: %A" result
result
we get
f: <fun:test#63>
inp: Some "something"
result: Some (String20 "something")
we see that f is a function which is String20
So how can String20 be a function?
If we send String20 to F# Interactive it gives.
> String20;;
val it : arg0:string -> String20 = <fun:clo#4>
So String20 is a function that takes a string and returns a type of String20. That smells of a constructor.
Let's test that out in F# interactive.
> let test1 = String20 "something";;
val test1 : String20 = String20 "something"
Sure enough, String20 is a constructor, but we didn't specifically create a constructor as is done in the Object-Oriented world.
You have to think of a type, even a discriminated union as having constructors. The constructors are not specifically written but do exist. So String20 is a constructor that takes one value, a string, which is a function with the correct type signature for the Option.map function.
I gave the answer a lot more detail so that one can learn a process on how to break down problems and look at the inner workings as a tool to solving these kinds of problems.
To learn more about the lower level details of how functional programming works one needs to understand lambda calculus. The best way I know to learn it is to read An Introduction To Functional Programming Through Lambda Calculus by Greg Michaelson and look at the info in the lambda calculus tag.
Also if you like the book, you should buy a copy instead of using the free version.
There are two ways of looking at it.
let f x y = x + y
// val f: x:int -> y:int -> int
One way is to say that function f takes two parameters, x of type int and y of type int, and returns an int. So I can supply two arguments and get the result:
let a = f 4 5
// val a: int = 9
The other way is that the function takes one parameter, x of type int, and returns another function, which takes one parameter, y of type int, and returns an int. So I can supply one argument and get a function as result:
let b = f 4
// val b: int -> int
Mathematically, it's always the second way - all functions are one-parameter functions. This notion is very convenient for programming with higher-order functions.
But the first way is usually more understandable to humans, so you will often see functions discussed as if they take multiple parameters.
String20 is the case constructor for the String20 Discriminated Union case. It's a function with the type string -> String20. So string takes the place of 'T, and String20 takes the place of 'U in the mapping you supply to Option.map.
Generally, if you have a function T1 -> T2 -> ... and you apply it to one parameter, you get a function T2 -> .... In the case of Option.map, T1 is itself a function, but that is of no consequence to the way the arguments are applied.
I find it confusing to call a function "option", a string "Titanium" and a type called String20 "Uranium", so I'll stick with type names.
You ask where the "returned function" that maps a string option to a String20 option is in the expression Option.map String20 suffix. It is simply
Option.map String20
Since String20 constructs a String20 from a string, Option.map String20 is a function that maps a string to a String20 if it is present, and to None otherwise.
If you write Option.map String20 suffix, this function is applied to suffix, which would be a string option. The result of this expression is a String20 option.

Function argument is null, even though a non-null argument is passed

F# newbie here, and sorry for the bad title, I'm not sure how else to describe it.
Very strange problem I'm having. Here's the relevant code snippet:
let calcRelTime (item :(string * string * string)) =
tSnd item
|>DateTime.Parse
|> fun x -> DateTime.Now - x
|> fun y -> (floor y.TotalMinutes).ToString()
|>makeTriple (tFst item) (tTrd item) //makeTriple switches y & z. How do I avoid having to do that?
let rec getRelativeTime f (l :(string * string * string) list) =
match l with
| [] -> f
| x :: xs -> getRelativeTime (List.append [calcRelTime x] f) xs
I step through it with Visual Studio and it clearly shows that x in getRelativeTime is a 3-tuple with a well-formed datetime string. But when I step to calcRelTime item is null. Everything ends up returning a 3-tuple that has the original datetime string, instead of one with the total minutes past. There's no other errors anywhere, until the that datetime string hits a function that expects it to be an integer string.
Any help would be appreciated! (along with any other F# style tips/suggestions for these functions).
item is null, because it hasn't been constructed yet out of its parts. The F# compiler compiles tupled parameters as separate actual (IL-level) parameters rather than one parameter of type Tuple<...>. If you look at your compiled code in ILSpy, you will see this signature (using C# syntax):
public static Tuple<string, string, string> calcRelTime(string item_0, string item_1, string item_2)
This is done for several reasons, including interoperability with other CLR languages as well as efficiency.
To be sure, the tuple itself is then constructed from these arguments (unless you have optimization turned on), but not right away. If you make one step (hit F11), item will obtain a proper non-null value.
You can also see these compiler-generated parameters if you go to Debug -> Windows -> Locals in Visual Studio.
As for why it's returning the original list instead of modified one, I can't really say: on my setup, everything works as expected:
> getRelativeTime [] [("x","05/01/2015","y")]
val it : (string * string * string) list = [("x", "y", "17305")]
Perhaps if you share your test code, I would be able to tell more.
And finally, what you're doing can be done a lot simpler: you don't need to write a recursive loop yourself, it's already done for you in the many functions in the List module, and you don't need to accept a tuple and then deconstruct it using tFst, tSnd, and tTrd, the compiler can do it for you:
let getRelativeTime lst =
let calcRelTime (x, time, y) =
let parsed = DateTime.Parse time
let since = DateTime.Now - parsed
let asStr = (floor since.TotalMinutes).ToString()
(x, asStr, y)
List.map calRelTime lst
let getRelativeTime' list =
let calc (a, b, c) = (a, c, (floor (DateTime.Now - (DateTime.Parse b)).TotalMinutes).ToString())
list |> List.map calc
Signature of the function is val getRelativeTime : list:('a * string * 'b) list -> ('a * 'b * string) list
You can deconstruct item in the function declaration to (a, b, c), then you don't have to use the functions tFst, tSnd and tTrd.
The List module has a function map that applies a function to each element in a list and returns a new list with the mapped values.

Why does this produce a value restriction exception?

I've created a function that returns a list containing only the even indexes as shown below:
let rec removeOddIdx xs =
match xs with
|[] -> []
|h::t -> (if t.Length % 2 = 0 then
[h]#removeOddIdx t
else
removeOddIdx t)
It works fine when I call it:
removeOddIdx [1;2;3;];;
However when I call it with an empty list:
removeOddIdx [];;
I get a Value Restriction exception - how come?
I've read up on value restrictions but I don't understand why it happens in my case.
Here is the precise error message:
Testing.fs(13,1): error FS0030: Value restriction. The value 'it' has been inferred to have generic type
val it : '_a list
Either define 'it' as a simple data term, make it a function with explicit arguments or, if you do not intend for it to be generic, add a type annotation.
The problem you're having is that the compiler doesn't know what type to give the return value. When you pass it [1;2;3] it can infer that the return type is int list, but if you pass it [], what is the type of the return value? It cannot be inferred from the usage, so you get a value restriction error.
One solution is to give the parameter a type like so:
> removeOddIdx ([]:int list);;
val it : int list = []
The other is to make the function specific rather than generic like this:
> let rec removeOddIdx (xs:int list) =
match xs with
|[] -> []
|h::t -> (if t.Length % 2 = 0 then
[h]#removeOddIdx t
else
removeOddIdx t);;
val removeOddIdx : xs:int list -> int list
> removeOddIdx [];;
val it : int list = []
Outside of the repl this is unlikely to be an issue since the parameter type is likely to be inferred from elsewhere in your code.

Resources