Reputation: 9431
I keep learning F# pattern matching with my simple function which should return square root if argument is number, argument otherwise. I've modified it a bit and it looks like as follows.
let my_sqrt (o: obj) =
match o with
| :? float as d -> (sqrt d).ToString()
| _ as x -> x.ToString()
It is working fine for my purpose, but what if I don't want to cast return value to string? How can I return "some object" and then use it in printfn "%A" (my_sqrt [| 1; 2; 3 |])
construction?
Upvotes: 0
Views: 1460
Reputation: 3431
I agree with Tomas that using a Discriminated Union would be better. There is no Either monad built into F# but you could use the Choice union to standardize the interface:
let my_sqrt (o : obj) =
match o with
| :? float as d -> Choice1Of2 (sqrt d)
| o -> Choice2Of2 o;;
Upvotes: 0
Reputation: 9805
As mentioned in TP answer, the general idea should be, wherever possible, to surface information to your type system.
It is then easier for you to read and reason your program, as you have named things.
That means F# can actually work for you and tell you when you made something wrong
That makes it always worth the investment.
Upvotes: 0
Reputation: 243041
Even though your example is just a demonstration of what you're trying to do, it is worth pointing out that this is probably not a good design. In F#, you would not normally use functions that operate on objects using casts - a better way to represent this would be a discriminated union:
type MyInput =
| Numeric of float
| Other of obj
let my_sqrt = function
| Numeric d -> Numeric (sqrt d)
| Other o -> Other o
This function works on a type that is either Numeric
or Other
, but thanks to the DU, you do not need any casting. I think something along these lines would be a better approach to your actual problem too.
Upvotes: 8
Reputation: 61
I think your function is ok. When you want to compute each square root, you have to map your function over array like this:
Array.map my_sqrt [| 1.0; 2.0; 3.0 |] |> printfn "%A"
Upvotes: 0
Reputation: 25516
I think you want
let my_sqrt (o: obj) =
match o with
| :? float as d -> (sqrt d) :> obj
| _ as x -> x
just upcast to object
Upvotes: 5