4 votes

ReasonML Inadéquation du type avec le même type

Je reçois une erreur de type alors que j'utilise le même type dans ReasonML. L'erreur est la suivante :

[1]   We've found a bug for you!
[1]   /Users/gt/work/real-and-open/frontend/src/domain/classroom/views/RosterLayoutHeader.re 42:10-70
[1]
[1]   40  <Classroom.Mutation.AddStudent>
[1]   41    ...{
[1]   42      (addStudent: (~id: UUID.t, ~classroomId: UUID.t, unit) => unit) =>
[1]         {
[1]   43        <div>
[1]   44          <StudentRowHeader
[1]
[1]   This pattern matches values of type
[1]     (~id: UUID.t, ~classroomId: UUID.t, unit) => unit
[1]   but a pattern was expected which matches values of type
[1]     AddStudent.ContainerMutation.mutationFunctionType (defined as
[1]       AddStudent.MutationInternals.mutationFunctionType)

Lorsque je remplace addStudent: (~id: UUID.t, ~classroomId: UUID.t, unit) => unit con addStudent: AddStudent.MutationInternals.mutationFunctionType

L'erreur devient :

[1]   We've found a bug for you!
[1]   /Users/gt/work/real-and-open/frontend/src/domain/classroom/views/RosterLayoutHeader.re 53:61-70
[1]
[1]   51  _ =>
[1]   52    updateClassroom(
[1]   53      Classroom.Action.ApolloAddStudent(() => addStudent(
[1]   54        ~id=classroom.local.newStudentId |> Student.Model.getUUIDFromId,
[1]   55        ~classroomId=classroom.data.id,
[1]
[1]   This expression has type AddStudent.MutationInternals.mutationFunctionType
[1]   It is not a function.

Dans le code, AddStudent ressemble à ce qui suit :

[@bs.config {jsx: 3}];
module Mutation = [%graphql
  {|
    mutation addStudent($id: ID!, $classroomId: ID!) {
      addStudent(student: {id: $id, classroomId: $classroomId}){
        ...Classroom_Model.Fragment.ClassroomFields
      }
    }
  |}
];

module MutationInternals : ApolloMutation.MutationInternal = {
  type mutationFunctionType = (~id: UUID.t, ~classroomId: UUID.t, unit) => unit;
  let componentName = "AddStudent";

  module Config = Mutation;
  module InternalMutation = ReasonApollo.CreateMutation(Config);

  let callMutationWithApollo = (apolloMutation : ApolloMutation.apolloMutationType(Config.t)) => 
    ((~id: UUID.t, ~classroomId: UUID.t, ()): unit => {
      let newStudent = Config.make(~id, ~classroomId, ());
      apolloMutation(
        ~variables=newStudent##variables,
        // ~refetchQueries=[|"member"|],
        // ~optimisticResponse=Config.t,
        (),
      ) |> ignore;
      () |> ignore;
    }: mutationFunctionType);
};

module ContainerMutation = ApolloMutation.CreateMutationContainer(MutationInternals);

module Jsx2 = ContainerMutation.Jsx2;
let make = ContainerMutation.make;

Notez donc 3 choses

1) Le type : type mutationFunctionType = (~id: UUID.t, ~classroomId: UUID.t, unit) => unit; est référencée ici et dans l'erreur il est dit AddStudent.MutationInternals.mutationFunctionType n'est pas compatible avec (~id: UUID.t, ~classroomId: UUID.t, unit) => unit même s'il s'agit de la même chose.

2) Lorsque je référence le type directement dans la fonction appelante, le message suivant s'affiche mutationFunctionType n'est pas une fonction et c'est une fonction.

3) J'utilise un Functor pour traiter mes modules MutationInternals... Je me demande si cela affecte les types.

Remerciements

4voto

ivg Points 20812

En AddStudent.MutationInternals.mutationFunctionType est abstrait et le compilateur ne sait pas que, sous le capot, il est en fait implémenté comme une fonction de type

(~id: UUID.t, ~classroomId: UUID.t, unit) => unit

Il est difficile de deviner quelle est la racine du problème dans votre cas. Soit vous avez accidentellement trop abstrait votre code, en scellant votre module, soit vous essayez de briser l'abstraction nécessaire. Dans tous les cas, le compilateur vous en empêche.

En général, ce type d'erreur se produit lorsque vous scellez votre module, par exemple lorsque vous ajoutez un type de module, par exemple,

module type S = {type t};
module M : S = { type t = int};

Cela rend le type M.t abstrait, il ne sera donc pas utilisable dans le contexte où le int est attendue. La solution consiste à supprimer ce scellement inutile, par exemple,

module type S = {type t};
module M = { type t = int};

ou indiquer explicitement au compilateur que t n'est pas un type abstrait, mais un type concret int , par exemple,

module type S = {type t};
module M: S with type t = int = {
  type t = int;
};

Notez que dans votre cas, je parle de ce morceau de code

MutationInternals : ApolloMutation.MutationInternal

qui cache le mutationFunctionType définition.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X