0

我一直在用我的简单函数学习 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 |])构造中使用它?

4

5 回答 5

8

尽管您的示例只是演示您正在尝试做的事情,但值得指出的是,这可能不是一个好的设计。在 F# 中,您通常不会使用使用强制类型转换对对象进行操作的函数 - 表示这一点的更好方法是区分联合:

type MyInput = 
  | Numeric of float
  | Other of obj

let my_sqrt = function
  | Numeric d -> Numeric (sqrt d)
  | Other o -> Other o

此函数适用于Numericor类型Other,但多亏了 DU,您不需要任何类型转换。我认为这些方面的东西也将是解决您的实际问题的更好方法。

于 2013-05-24T09:08:57.527 回答
5

我想你想要

let my_sqrt (o: obj) =
  match o with
  | :? float as d -> (sqrt d) :> obj
  | _ as x -> x

只是向上反对

于 2013-05-23T11:18:01.247 回答
0

正如 TP 答案中提到的,一般的想法应该是尽可能地向您的类型系统显示信息。

  • 这样你就更容易阅读和推理你的程序,因为你已经命名了。

  • 这意味着 F# 实际上可以为您工作,并在您犯错时告诉您

这使得它总是值得投资。

于 2013-05-24T10:10:08.487 回答
0

我同意 Tomas 的观点,即使用有区别的联盟会更好。F# 中没有内置 Either monad,但您可以使用 Choice 联合来标准化接口:

let my_sqrt (o : obj) = 
  match o with 
  | :? float as d -> Choice1Of2 (sqrt d) 
  | o -> Choice2Of2 o;;
于 2013-05-24T10:49:43.430 回答
0

我觉得你的功能没问题。当你想计算每个平方根时,你必须像这样将你的函数映射到数组上:

Array.map my_sqrt [| 1.0; 2.0; 3.0 |] |> printfn "%A"
于 2013-05-23T11:32:14.477 回答