我继续学习F#模式匹配我的简单函数,如果参数是数字,则返回平方根,否则返回参数。我对它进行了一些修改,看起来如下所示。
let my_sqrt (o: obj) =
match o with
| :? float as d -> (sqrt d).ToString()
| _ as x -> x.ToString()
它的工作正常,但如果我不想将返回值转换为字符串怎么办?如何返回“某个对象”然后在printfn "%A" (my_sqrt [| 1; 2; 3 |])
构造中使用它?
答案 0 :(得分:8)
即使你的例子只是你要做的事情的示范,但值得指出的是,这可能不是一个好的设计。在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,您不需要任何强制转换。我认为这些方面的内容也可以更好地解决您的实际问题。
答案 1 :(得分:5)
我想你想要
let my_sqrt (o: obj) =
match o with
| :? float as d -> (sqrt d) :> obj
| _ as x -> x
刚刚转向对象
答案 2 :(得分:0)
我认为你的功能还可以。当你想要计算每个平方根时,你必须将你的函数映射到数组上,如下所示:
Array.map my_sqrt [| 1.0; 2.0; 3.0 |] |> printfn "%A"
答案 3 :(得分:0)
正如TP回答中提到的那样,一般的想法应该是,尽可能将信息表面化到您的类型系统。
您可以 来阅读和推理您的计划,因为您有命名的内容。
这意味着F#实际上可以为你工作并告诉你什么时候出错了
这使得它总是值得投资。
答案 4 :(得分:0)
我同意托马斯的看法,认为使用歧视联盟会更好。 F#中没有内置Ead monad,但您可以使用Choice联合来标准化接口:
let my_sqrt (o : obj) =
match o with
| :? float as d -> Choice1Of2 (sqrt d)
| o -> Choice2Of2 o;;