Por que a informação do tipo na caixa vermelha não é: 'a -> 'a -> 'a -> 'a -> 'a
?
Acho que todos os parâmetros e o valor de retorno devem ser do mesmo tipo, e o utop confirma que todos eles são do mesmo Z.t
tipo.
utop # let rec fib_acc = fun n -> fun n_1 -> fun n_2 -> fun acc ->
if (Z.equal n Z.one) || (Z.equal n (Z.of_int 2))
then acc
else fib_acc (Z.add n Z.minus_one) n_2 (Z.add n_1 n_2) (Z.add n_1 n_2);;
val fib_acc : Z.t -> Z.t -> Z.t -> Z.t -> Z.t = <fun>
O que sabemos sobre os tipos de
Z.add
,Z.equal
,Z.one
,Z.minus_one
eZ.of_int
?Você precisa dessa informação se quiser concluir que
n, n_1, n_2
todosacc
têm o tipoZ.t
.Sem saber os tipos de funções
Z.add
eZ.equal
, podemos concluir queacc
e o valor de retorno têm o mesmo tipo, por causa dothen acc
branch, e podemos concluir quen_1
en_2
têm o mesmo tipo, porquen_2
em lugar den_1
na chamada recursiva. Isso explica o tipo'a -> 'b -> 'b -> 'c -> 'c
.Presumivelmente,
utop
tem acesso aos tipos deZ.add
eZ.equal
, mas o software que fornece a dica de tipo'a -> 'b -> 'b -> 'c -> 'c
não tem acesso a essas informações.Além da resposta de stef , parece que você está cometendo um erro muito comum para novos programadores de OCaml: usar diretivas de nível superior em arquivos de código-fonte. Em vez de usar,
#require
você precisa garantir que está compilando corretamente para vincular a biblioteca Zarith.Você pode usar dune, mas isso provavelmente é exagero neste estágio. Neste ponto,
ocamlfind
fará o trabalho muito bem.Com seu arquivo de origem agora sendo:
Mas isso pode se tornar mais legível se abrirmos
Z
e redefinirmos localmente=
. Adicionarminus_one
também pode ser subtrairone
.Note também que os valores que você está passando para
n_2
eacc
são os mesmos. Oacc
argumento é desnecessário. Sua função pode ser simplificada.Mas você provavelmente também quer esconder esses dois últimos argumentos de qualquer forma, pois há valores definidos que você sempre quer fornecer na primeira chamada. Não faria sentido chamar,
Z.(fib_acc (of_int 67) (of_int 34) (of_int 3))
por exemplo.