我一直在学习f#模式匹配我的简单函数,如果参数是数字,则应该返回平方根,否则参数。我稍微修改了一下,它看起来像这样。
let my_sqrt (o: obj) =
match o with
| :? float as d -> (sqrt d).ToString()
| _ as x -> x.ToString()
对于我的目的来说它工作得很好,但是如果我不想将返回值转换为string怎么办?我怎么能返回"一些对象",然后在printfn "%A" (my_sqrt [| 1; 2; 3 |])
建设中使用它?
尽管您的示例只是演示了您要做的事情,但值得指出的是,这可能不是一个好的设计。在f#中,您通常不会使用使用强制类型转换对对象进行操作的函数-更好的表示方式是区分联合:
type MyInput =
| Numeric of float
| Other of obj
let my_sqrt = function
| Numeric d -> Numeric (sqrt d)
| Other o -> Other o
此函数作用于Numeric
或Other
类型,但由于DU,您不需要任何强制转换。
我想你要
let my_sqrt (o: obj) =
match o with
| :? float as d -> (sqrt d) :> obj
| _ as x -> x
只是向上转换为对象
我认为你的功能是可以的。当您想要计算每个平方根时,您必须像这样将函数映射到数组上:
Array.map my_sqrt [| 1.0; 2.0; 3.0 |] |> printfn "%A"
正如在TP回答中提到的,一般的思想应该是尽可能地向类型系统显示信息。
-
这是更容易你阅读和推理你的程序,因为你有命名的东西。
-
这意味着f#实际上可以为你工作并告诉你什么时候你做错了
我同意Tomas的观点,使用discrimination Union会更好。f#中没有内置的Either单子,但是你可以使用Choice联合来标准化接口:
let my_sqrt (o : obj) =
match o with
| :? float as d -> Choice1Of2 (sqrt d)
| o -> Choice2Of2 o;;