List 带有字符列表的OCaml对int

List 带有字符列表的OCaml对int,list,pattern-matching,ocaml,signature,caml,List,Pattern Matching,Ocaml,Signature,Caml,我正在使用一个函数,原型保留列表,它需要签名valremaining:char list->int*char list=。我是Ocaml新手,我不知道如何使Ocaml函数只接受一个列表并同时输出一个int和一个列表。这是我目前正在使用的代码 let rec remaining thelist= match thelist with | [] -> [] | [x] -> [x] | x::y::t1 -> if x='a' then remaining

我正在使用一个函数,原型
保留列表
,它需要签名
valremaining:char list->int*char list=
。我是Ocaml新手,我不知道如何使Ocaml函数只接受一个列表并同时输出一个int和一个列表。这是我目前正在使用的代码

let rec remaining thelist= match thelist with
  | [] -> []
  | [x] -> [x]
  | x::y::t1 ->
      if x='a' then remaining (y::t1)
      else thelist;;

match thelist with
  | [] -> 0
  | x::t1 -> 
    if x='a' then 1+remaining t1
    else 0;;
如果注释掉第二个代码块,第一个代码块将输出正确的字符列表。如果注释掉第一个块,第二个块将输出正确的int。我不知道如何组合代码以实现所需的签名,而不会出现某种兼容性错误

您可以使用产品类型(实际上您的签名建议您这样做)和“隐藏”本地函数

let remaining =
     let rec f i = function
       | 'a'::l -> f (i+1) l
       | l -> i, l
     in
     f 0

这似乎是另一个问题的重复:@JeffreyScofield Hm…但是如果将函数更改为包含两个参数,是否会将签名更改为int*char list->int*char list?没有人建议更改输入参数,只有结果。本质上,关键是对递归调用的结果进行分解。