I am having trouble with the following:
let safeDiv x y =
match (x,y) with
| (_, Some 0) -> None
| (Some xx, Some yy) -> Some (xx/yy)
| _ -> None
When I go to run this simple function in the interactive window of Visual Studio like so:
safeDiv 4 2
I get the following error...
This expression was expected to have type int option but here has type int.
Could it be I'm meant to use safeDiv Some(4) Some(2)? This doesn't work either...
Ok, this is overkill but I actually did something similar to this recently.
First I defined a computation expression builder for the option type:
type OptionBuilder() =
member this.Bind(x, f) = Option.bind f x
member this.Return(x) = Some x
member this.ReturnFrom(x) = x
let opt = new OptionBuilder()
And then I defined a function sub of type float -> float -> float option
let sub x y = if y = 0.0 then None else Some (x / y)
And finally I used the OptionBuilder to define saveDiv as float option -> float option -> float option
let safeDiv x y = opt { let! a = x
let! b = y
return! sub a b }
You can read more about computation expressions on wikibooks: http://en.wikibooks.org/wiki/F_Sharp_Programming/Computation_Expressions
And if you want to dive deeper into the theory behind this, you can read this paper by Tomas Petricek and Don Syme: http://www.cl.cam.ac.uk/~tp322/drafts/notations.pdf
Your second version was close.
It should be
safeDiv (Some(4)) (Some(2))
The extra brackets are required to make sure that functions are applied in the correct order.
You constructed a function that has the signature safeDiv : int option -> int option -> int option. You need to use an entry like safeDiv (Some 4) (Some 2) to use your function as is.
The problem is in the matching of (4, 2), of type int*int, with the expressions (_, Some 0) and (Some xx, Some yy). The whole function can be simplified:
let safeDiv x y =
match (x,y) with
| (_, 0) -> None
| (_, _) -> Some (x/y)
Making the following call valid
safeDiv 4 2
Related
type Interpreter<'a> =
| RegularInterpreter of (int -> 'a)
| StringInterpreter of (string -> 'a)
let add<'a> (x: 'a) (y: 'a) (in_: Interpreter<'a>): 'a =
match in_ with
| RegularInterpreter r ->
x+y |> r
| StringInterpreter r ->
sprintf "(%s + %s)" x y |> r
The error message of it not being able to resolve 'a at compile time is pretty clear to me. I am guessing that the answer to the question of whether it is possible to make the above work is no, short of adding functions directly into the datatype. But then I might as well use an interface, or get rid of generic parameters entirely.
Edit: Mark's reply does in fact do what I asked, but let me extend the question as I did not explain it adequately. What I am trying to do is do with the technique above is imitate what what was done in this post. The motivation for this is to avoid inlined functions as they have poor composability - they can't be passed as lambdas without having their generic arguments specialized.
I was hoping that I might be able to work around it by passing an union type with a generic argument into a closure, but...
type Interpreter<'a> =
| RegularInterpreter of (int -> 'a)
| StringInterpreter of (string -> 'a)
let val_ x in_ =
match in_ with
| RegularInterpreter r -> r x
| StringInterpreter r -> r (string x)
let inline add x y in_ =
match in_ with
| RegularInterpreter r ->
x in_ + y in_ |> r
| StringInterpreter r ->
sprintf "(%A + %A)" (x in_) (y in_) |> r
let inline mult x y in_ =
match in_ with
| RegularInterpreter r ->
x in_ * y in_ |> r
| StringInterpreter r ->
sprintf "(%A * %A)" (x in_) (y in_) |> r
let inline r2 in_ = add (val_ 1) (val_ 3) in_
r2 (RegularInterpreter id)
r2 (StringInterpreter id) // Type error.
This last line gives a type error. Is there a way around this? Though I'd prefer the functions to not be inlined due to the limits they place on composability.
Remove the type annotations:
let inline add x y in_ =
match in_ with
| RegularInterpreter r ->
x + y |> r
| StringInterpreter r ->
sprintf "(%A + %A)" x y |> r
You'll also need to make a few other changes, which I've also incorporated above:
Change the format specifiers used with sprintf to something more generic. When you use %s, you're saying that the argument for that placeholder must be a string, so the compiler would infer x and y to be string values.
Add the inline keyword.
With these changes, the inferred type of add is now:
x: ^a -> y: ^b -> in_:Interpreter<'c> -> 'c
when ( ^a or ^b) : (static member ( + ) : ^a * ^b -> int)
You'll notice that it works for any type where + is defined as turning the input arguments into int. In practice, that's probably going to mean only int itself, unless you define a custom operator.
FSI smoke tests:
> add 3 2 (RegularInterpreter id);;
val it : int = 5
> add 2 3 (StringInterpreter (fun _ -> 42));;
val it : int = 42
The compiler ends up defaulting to int, and the kind of polymorphism you want is difficult to achieve in F#. This article articulates the point.
Perhaps, you could work the dark arts using FSharp.Interop.Dynamic but you lose compile time checking which sort of defeats the point.
I've come to the conclusion that what I am trying to is impossible. I had a hunch that it was already, but the proof is in the following:
let vale (x,_,_) = x
let adde (_,x,_) = x
let multe (_,_,x) = x
let val_ x d =
let f = vale d
f x
let add x y d =
let f = adde d
f (x d) (y d)
let mult x y d =
let f = multe d
f (x d) (y d)
let in_1 =
let val_ (x: int) = x
let add x y = x+y
let mult x y = x*y
val_,add,mult
let in_2 =
let val_ (x: int) = string x
let add x y = sprintf "(%s + %s)" x y
let mult x y = sprintf "(%s * %s)" x y
val_,add,mult
let r2 d = add (val_ 1) (val_ 3) d
//let test x = x in_1, x in_2 // Type error.
let a2 = r2 in_1 // Works
let b2 = r2 in_2 // Works
The reasoning goes that if it cannot be done with plain functions passed as arguments, then it definitely won't be possible with interfaces, records, discriminated unions or any other scheme. The standard functions are more generic than any of the above, and if they cannot do it then this is a fundamental limitation of the language.
It is not the lack of HKTs that make the code ungeneric, but something as simple as this. In fact, going by the Finally Tagless paper linked to in the Reddit post, Haskell has the same problem with needing to duplicate interpreters without the impredicative types extension - though I've looked around and it seem that impredicative types will be removed in the future as the extension is difficult to maintain.
Nevertheless, I do hope this is only a current limitation of F#. If the language was dynamic, the code segment above would in fact run correctly.
Unfortunately, it's not completely clear to me what you're trying to do. However, it seems likely that it's possible by creating an interface with a generic method. For example, here's how you could get the code from your answer to work:
type I = abstract Apply : ((int -> 'a) * ('a -> 'a -> 'a) * ('a -> 'a -> 'a)) -> 'a
//let test x = x in_1, x in_2 // Type error.
let test (i:I) = i.Apply in_1, i.Apply in_2
let r2' = { new I with member __.Apply d = add (val_ 1) (val_ 3) d }
test r2' // no problem
If you want to use a value (e.g. a function input) generically, then in most cases the cleanest way is to create an interface with a generic method whose signature expresses the required polymorphism.
I m trying to filter a mixed data type for a specific type, say float (ideally this would be dynamic though)
here my example:
let testobj = [8.0 , 1.0, "bla" ; 8.0 , 1.0, "bla"]
let testfun data = data |> List.filter (fun a ->
match a.GetType() with
| float -> a
| _ -> 0.0)
now this should return [8.0 , 1.0, 0.0 ; 8.0 , 1.0, 0.0] for testobj but I m gettting an error that the function is of type bool
This isn't what you want to do.
Seriously.
F# wants lists to be homogeneous and your list is not homogeneous. float and string don't share a common base class so you're not going to get a list from it.
What F# wants you to do is to use a discriminated union for this. So if you have this type:
type Composite =
| Num of float
| Str of string
you can define your list like this:
let data = [ Num(8.0); Num(1.0); Str("bla"); Num(8.0); Num(1.0); Str("bla") ]
and from there you can pattern match on the types and your function looks like this:
let testfun d = d |> List.map (fun a ->
match a with
| Num x -> a
| _ -> Num(0.0) )
data|> testfun |> printfn "%A"
And the output will be:
[Num 8.0; Num 1.0; Num 0.0; Num 8.0 ; Num 1.0 ; Num 0.0;]
If you want floats in the end and not Composites, do this:
let testfun1 d = d |> List.map (fun a ->
match a with
| Num x -> x
| _ -> 0.0 )
which sheds the composite type. And everything (and I mean everything) in that code is type strong and type-safe.
From a real-world maintenance point of view, I would eschew the _ case in the matches and instead use all my types, reasoning that if I extend Composite to include another type I would want the compiler to scream at me and look at each function that uses it rather than silently assuming that 0.0 or Num(0.0) is really what I wanted.
For example, if I added integers to that type, this would do exactly the wrong thing if I wanted to sum the contents of a list of composites.
Given that you're stuck/hell-bent on a weakly-typed data set, then you want something like this:
let testfun2 d = d |> Array.map (fun (a:Object) ->
match a with
| :? float as x -> x
| _ -> 0.0
)
let data:Object[] = [|8.0; 1.0; "bla"; 8.0; 1.0; "bla"|]
data |> testfun2 |> printfn "%A"
which will print what you expect. Note that I'm using proper Array syntax and not list syntax.
However this is feeling really wonky for F#. See how I have to adorn a and d with types? In my previous code, the language can figure it all out. If I don't adorn either, I get compiler errors because we're really going against the grain of the type system.
If I were you, I would be inclined to do something like this first:
let recast d = d |> Array.map (fun (a:Object) ->
match a with
| :? float as x -> Num x
| :? string as x -> Str x
| _ -> raise (ArgumentException("that was unexpected: " + a.GetType().Name))
)
which turns this into an Array of Composite which is now type strong. If you tack on |> Array.toList after the Array.map, you get a list (if you want that).
I am currently experimenting with F#. The articles found on the internet are helpful, but as a C# programmer, I sometimes run into situations where I thought my solution would help, but it did not or just partially helped.
So my lack of knowledge of F# (and most likely, how the compiler works) is probably the reason why I am totally flabbergasted sometimes.
For example, I wrote a C# program to determine perfect numbers. It uses the known form of Euclids proof, that a perfect number can be formed from a Mersenne Prime 2p−1(2p−1) (where 2p-1 is a prime, and p is denoted as the power of).
Since the help of F# states that '**' can be used to calculate a power, but uses floating points, I tried to create a simple function with a bitshift operator (<<<) (note that I've edit this code for pointing out the need):
let PowBitShift (y:int32) = 1 <<< y;;
However, when running a test, and looking for performance improvements, I also tried a form which I remember from using Miranda (a functional programming language also), which uses recursion and a pattern matcher to calculate the power. The main benefit is that I can use the variable y as a 64-bit Integer, which is not possible with the standard bitshift operator.
let rec Pow (x : int64) (y : int64) =
match y with
| 0L -> 1L
| y -> x * Pow x (y - 1L);;
It turns out that this function is actually faster, but I cannot (yet) understand the reason why. Perhaps it is a less intellectual question, but I am still curious.
The seconds question then would be, that when calculating perfect numbers, you run into the fact that the int64 cannot display the big numbers crossing after finding the 9th perfectnumber (which is formed from the power of 31). I am trying to find out if you can use the BigInteger object (or bigint type) then, but here my knowledge of F# is blocking me a bit. Is it possible to create a powerfunction which accepts both arguments to be bigints?
I currently have this:
let rec PowBigInt (x : bigint) (y : bigint) =
match y with
| bigint.Zero -> 1I
| y -> x * Pow x (y - 1I);;
But it throws an error that bigint.Zero is not defined. So I am doing something wrong there as well. 0I is not accepted as a replacement, since it gives this error:
Non-primitive numeric literal constants cannot be used in pattern matches because they
can be mapped to multiple different types through the use of a NumericLiteral module.
Consider using replacing with a variable, and use 'when <variable> = <constant>' at the
end of the match clause.
But a pattern matcher cannot use a 'when' statement. Is there another solution to do this?
Thanks in advance, and please forgive my long post. I am only trying to express my 'challenges' as clear as I can.
I failed to understand why you need y to be an int64 or a bigint. According to this link, the biggest known Mersenne number is the one with p = 43112609, where p is indeed inside the range of int.
Having y as an integer, you can use the standard operator pown : ^T -> int -> ^T instead because:
let Pow (x : int64) y = pown x y
let PowBigInt (x: bigint) y = pown x y
Regarding your question of pattern matching bigint, the error message indicates quite clearly that you can use pattern matching via when guards:
let rec PowBigInt x y =
match y with
| _ when y = 0I -> 1I
| _ -> x * PowBigInt x (y - 1I)
I think the easiest way to define PowBigInt is to use if instead of pattern matching:
let rec PowBigInt (x : bigint) (y : bigint) =
if y = 0I then 1I
else x * PowBigInt x (y - 1I)
The problem is that bigint.Zero is a static property that returns the value, but patterns can only contain (constant) literals or F# active patterns. They can't directly contain property (or other) calls. However, you can write additional constraints in where clause if you still prefer match:
let rec PowBigInt (x : bigint) (y : bigint) =
match y with
| y when y = bigint.Zero -> 1I
| y -> x * PowBigInt x (y - 1I)
As a side-note, you can probably make the function more efficent using tail-recursion (the idea is that if a function makes recursive call as the last thing, then it can be compiled more efficiently):
let PowBigInt (x : bigint) (y : bigint) =
// Recursive helper function that stores the result calculated so far
// in 'acc' and recursively loops until 'y = 0I'
let rec PowBigIntHelper (y : bigint) (acc : bigint) =
if y = 0I then acc
else PowBigIntHelper (y - 1I) (x * acc)
// Start with the given value of 'y' and '1I' as the result so far
PowBigIntHelper y 1I
Regarding the PowBitShift function - I'm not sure why it is slower, but it definitely doesn't do what you need. Using bit shifting to implement power only works when the base is 2.
You don't need to create the Pow function.
The (**) operator has an overload for bigint -> int -> bigint.
Only the second parameter should be an integer, but I don't think that's a problem for your case.
Just try
bigint 10 ** 32 ;;
val it : System.Numerics.BigInteger =
100000000000000000000000000000000 {IsEven = true;
IsOne = false;
IsPowerOfTwo = false;
IsZero = false;
Sign = 1;}
Another option is to inline your function so it works with all numeric types (that support the required operators: (*), (-), get_One, and get_Zero).
let rec inline PowBigInt (x:^a) (y:^a) : ^a =
let zero = LanguagePrimitives.GenericZero
let one = LanguagePrimitives.GenericOne
if y = zero then one
else x * PowBigInt x (y - one)
let x = PowBigInt 10 32 //int
let y = PowBigInt 10I 32I //bigint
let z = PowBigInt 10.0 32.0 //float
I'd probably recommend making it tail-recursive, as Tomas suggested.
In my quest to learn more F#, I tried to implement an "accumulator generator" as described by Paul Graham here. My best solution so far is completely dynamically typed:
open System
let acc (init:obj) : obj->obj=
let state = ref init
fun (x:obj) ->
if (!state).GetType() = typeof<Int32>
&& x.GetType() = typeof<Int32> then
state := (Convert.ToInt32(!state) + Convert.ToInt32(x)) :> obj
else
state := (Convert.ToDouble(!state) + Convert.ToDouble(x)) :> obj
!state
do
let x : obj -> obj = acc 1 // the type annotation is necessary here
(x 5) |> ignore
printfn "%A" (x 2) // prints "8"
printfn "%A" (x 2.3) // prints "10.3"
I have three questions:
If I remove the type annotation for x, the code fails to compile because the compiler infers type int -> obj for x - although acc is annotated to return an obj->obj. Why is that and can I avoid it?
Any ideas to improve this dynamically typed version?
Is it possible to implement this with proper static types? Maybe with member constraints? (It is possible in Haskell, but not in OCaml, AFAIK)
In my quest to learn more F#, I tried to implement an "accumulator generator" as described by Paul Graham here.
This problem requires the existence of an unspecified numeric tower. Lisp happens to have one and it happens to be adequate for Paul Graham's examples because this problem was specifically designed to make Lisp look artificially good.
You can implement a numeric tower in F# either using a union type (like type number = Int of int | Float of float) or by boxing everything. The following solution uses the latter approach:
let add (x: obj) (y: obj) =
match x, y with
| (:? int as m), (:? int as n) -> box(m+n)
| (:? int as n), (:? float as x)
| (:? float as x), (:? int as n) -> box(x + float n)
| (:? float as x), (:? float as y) -> box(x + y)
| _ -> failwith "Run-time type error"
let acc x =
let x = ref x
fun (y: obj) ->
x := add !x y
!x
let x : obj -> _ = acc(box 1)
do x(box 5)
do acc(box 3)
do printfn "%A" (x(box 2.3))
However, numeric towers are virtually useless in the real world. Unless you are very careful, trying to learn from these kinds of borked challenges will do you more harm than good. You should leave asking yourself why we do not want a numeric tower, do not want to box and do not want run-time type promotion?
Why didn't we just write:
let x = 1
let x = x + 5
ignore(3)
let x = float x + 2.3
We know the type of x at every step. Every number is stored unboxed. We know that this code will never produce a run-time type error...
I agree with Jon that this is quite artificial example and it is not a good starting point for learning F#. However, you can use static member constraints to get reasonably close without dynamic casts and reflection. If you mark it as inline and add convert both of the parameters using float:
let inline acc x =
let x = ref (float x)
fun y ->
x := (float y) + !x
!x
You'll get a function with the following type:
val inline acc :
^a -> ( ^b -> float)
when ^a : (static member op_Explicit : ^a -> float) and
^b : (static member op_Explicit : ^b -> float)
The function takes any two arguments that can be explicitly converted to float. The only limitation compared to the LISP version (I guess) is that it always returns float (as the most universal numeric type available). You can write something like:
> acc 1 2;; // For two integers, it returns float
val it : float = 3.0
> acc 1 2.1;; // integer + float
val it : float = 3.1
> acc 1 "31";; // It even works with strings!
val it : float = 32.0
It's definitely not possible to implement this with proper static types. You say you can in Haskell, but I don't believe you.
The problem with trying to do this with static typing is in adding two different numbers of possibly different types while preserving the type of the left-hand side. As Jon Harrop says this is possible with a union type. Once you've defined the union type and a corresponding addition operation which works as mentioned, the actual accumulator is very simple. My implementation:
module MyTest
type Numeric =
| NInt of int
| NFloat of float
member this.Add(other : Numeric) : Numeric =
match this with
| NInt x ->
match other with
| NInt y -> NInt (x + y)
| NFloat y -> NInt (x + (int y))
| NFloat x ->
match other with
| NInt y -> NFloat (x + (float y))
| NFloat y -> NFloat (x + y)
override this.ToString() =
match this with
| NInt x -> x.ToString()
| NFloat x -> x.ToString()
let foo (n : Numeric) =
let acc = ref n
fun i ->
acc := (!acc).Add(i)
!acc
let f = foo (NFloat 1.1)
(2 |> NInt |> f).ToString() |> printfn "%s"
I'm just starting up with F# and see how you can use currying to pre-load the 1st parameter to a function. But how would one do it with the 2nd, 3rd, or whatever other parameter? Would named parameters to make this easier? Are there any other functional languages that have named parameters or some other way to make currying indifferent to parameter-order?
Typically you just use a lambda:
fun x y z -> f x y 42
is a function like 'f' but with the third parameter bound to 42.
You can also use combinators (like someone mentioned Haskell's "flip" in a comment), which reorder arguments, but I sometimes find that confusing.
Note that most curried functions are written so that the argument-most-likely-to-be-partially-applied comes first.
F# has named parameters for methods (not let-bound function values), but the names apply to 'tupled' parameters. Named curried parameters do not make much sense; if I have a two-argument curried function 'f', I would expect that given
let g = f
let h x y = f x y
then 'g' or 'h' would be substitutable for 'f', but 'named' parameters make this not necessarily true. That is to say, 'named parameters' can interact poorly with other aspects of the language design, and I personally don't know of a good design offhand for 'named parameters' that interacts well with 'first class curried function values'.
OCaml, the language that F# was based on, has labeled (and optional) arguments that can be specified in any order, and you can partially apply a function based on those arguments' names. I don't believe F# has this feature.
You might try creating something like Haskell's flip function. Creating variants that jump the argument further in the argument list shouldn't be too hard.
let flip f a b = f b a
let flip2 f a b c = f b c a
let flip3 f a b c d = f b c d a
Just for completeness - and since you asked about other functional languages - this is how you would do it in OCaml, arguably the "mother" of F#:
$ ocaml
# let foo ~x ~y = x - y ;;
val foo : x:int -> y:int -> int = <fun>
# foo 5 3;;
- : int = 2
# let bar = foo ~y:3;;
val bar : x:int -> int = <fun>
# bar 5;;
- : int = 2
So in OCaml you can hardcode any named parameter you want, just by using its name (y in the example above).
Microsoft chose not to implement this feature, as you found out... In my humble opinion, it's not about "poor interaction with other aspects of the language design"... it is more likely because of the additional effort this would require (in the language implementation) and the delay it would cause in bringing the language to the world - when in fact only few people would (a) be aware of the "stepdown" from OCaml, (b) use named function arguments anyway.
I am in the minority, and do use them - but it is indeed something easily emulated in F# with a local function binding:
let foo x y = x - y
let bar x = foo x 3
bar ...
It's possible to do this without declaring anything, but I agree with Brian that a lambda or a custom function is probably a better solution.
I find that I most frequently want this for partial application of division or subtraction.
> let halve = (/) >> (|>) 2.0;;
> let halfPi = halve System.Math.PI;;
val halve : (float -> float)
val halfPi : float = 1.570796327
To generalize, we can declare a function applySecond:
> let applySecond f arg2 = f >> (|>) arg2;;
val applySecond : f:('a -> 'b -> 'c) -> arg2:'b -> ('a -> 'c)
To follow the logic, it might help to define the function thus:
> let applySecond f arg2 =
- let ff = (|>) arg2
- f >> ff;;
val applySecond : f:('a -> 'b -> 'c) -> arg2:'b -> ('a -> 'c)
Now f is a function from 'a to 'b -> 'c. This is composed with ff, a function from 'b -> 'c to 'c that results from the partial application of arg2 to the forward pipeline operator. This function applies the specific 'b value passed for arg2 to its argument. So when we compose f with ff, we get a function from 'a to 'c that uses the given value for the 'b argument, which is just what we wanted.
Compare the first example above to the following:
> let halve f = f / 2.0;;
> let halfPi = halve System.Math.PI;;
val halve : f:float -> float
val halfPi : float = 1.570796327
Also compare these:
let filterTwoDigitInts = List.filter >> (|>) [10 .. 99]
let oddTwoDigitInts = filterTwoDigitInts ((&&&) 1 >> (=) 1)
let evenTwoDigitInts = filterTwoDigitInts ((&&&) 1 >> (=) 0)
let filterTwoDigitInts f = List.filter f [10 .. 99]
let oddTwoDigitInts = filterTwoDigitInts (fun i -> i &&& 1 = 1)
let evenTwoDigitInts = filterTwoDigitInts (fun i -> i &&& 1 = 0)
Alternatively, compare:
let someFloats = [0.0 .. 10.0]
let theFloatsDividedByFour1 = someFloats |> List.map ((/) >> (|>) 4.0)
let theFloatsDividedByFour2 = someFloats |> List.map (fun f -> f / 4.0)
The lambda versions seem to be easier to read.
In Python, you can use functools.partial, or a lambda. Python has named arguments.
functools.partial can be used to specify the first positional arguments as well as any named argument.
from functools import partial
def foo(a, b, bar=None):
...
f = partial(foo, bar='wzzz') # f(1, 2) ~ foo(1, 2, bar='wzzz')
f2 = partial(foo, 3) # f2(5) ~ foo(3, 5)
f3 = lambda a: foo(a, 7) # f3(9) ~ foo(9, 7)