您描述的输入数据无法在OCaml中表示 . OCaml是强类型的 . 例如,您的示例输入列表是OCaml中的无效值:
# [(1,1.0);(0.4,1);(0,0)];;
Error: This expression has type float but an expression was expected of type
int
所以你所描述的问题的本质(不知道类型)实际上是不可能的 . 您将不得不使用其他一些表示输入的方法 . 例如,你可以只使用浮点数 . 或者你可以使用成对的字符串 .
Update
重写问题的答案是一样的 . 在OCaml中,不可能不知道静态的类型;即,在您无法(或必要)在运行时查询某事物的类型时 . 所以你的问题没有答案(至少就我所见) .
对于OCaml,您必须考虑类型系统而不是反对它 . 过了一段时间,你开始真的喜欢它(或者至少那个's how it worked for me). I'开始写下你希望你的功能 myconverstion 具有的类型 .
Update 2
我会重复我的建议,将你的输入视为字符串 . 假设您已将输入解析为字符串对,这里有一些代码可以满足您的需求:
let myconversion coords =
let c1 s =
if String.contains s '.' then
Float (float_of_string s)
else
Int (int_of_string s)
in
let cp (a, b) = [c1 a; c1 b] in
List.map cp coords
以下是它对输入的作用(重新解释为字符串):
# myconversion [("1", "1.0"); ("0.4", "1"); ("0", "0")];;
- : fi list list = [[Int 1; Float 1.]; [Float 0.4; Int 1]; [Int 0; Int 0]]
Update 3
这是一些(粗略的)代码,它将数字文件解析为表示为字符串对的坐标 . 只要输入中的元组形成良好,它就应该工作 .
let coords fname =
let ic = open_in fname in
let len = in_channel_length ic in
let buf = Buffer.create 128 in
let () = Buffer.add_channel buf ic len in
let () = close_in ic in
let s = Buffer.contents buf in
let nums = Str.(split (regexp "[^0-9.]+") s) in
let rec mkcoords sofar = function
| [] | [_] -> List.rev sofar
| a :: b :: rest -> mkcoords ((a, b) :: sofar) rest
in
mkcoords [] nums