Loading ...
Sorry, an error occurred while loading the content.

Re: "ocaml_beginners"::[] changing names => from in_channel to unit ?!

Expand Messages
  • Stalkern 2
    Il Friday 14 March 2003 00:33, oliver@first.in-berlin.de ha scritto: [...] ... Look: # read_line;; - : unit - string = : while you probably want to use
    Message 1 of 6 , Mar 13, 2003
    • 0 Attachment
      Il Friday 14 March 2003 00:33, oliver@...-berlin.de ha scritto:

      [...]

      > let fl = Stack.create()
      >
      >
      > let input_header chan =
      > let rec read_lines_helper res =
      > let sl =
      > try
      > Some (Stack.pop fl)
      > with _ -> begin
      > try
      > Some (read_line chan)
      > with
      > End_of_file -> None (* no new headers *)
      > end
      > in
      > match sl with
      > None -> List.rev res
      > | Some line when String.length line = 0 -> List.rev res (* Header
      > complete *) | Some l -> read_lines_helper (l :: res) (* prepend new line
      > *) in
      > read_lines_helper []
      >

      Look:

      # read_line;;
      - : unit -> string = <fun>:

      while you probably want to use

      # input;;
      - : in_channel -> string -> int -> int -> int = <fun>

      with some buffer string as for copying files.

      If you look at code, generally you see where types are inferred. Here you were
      afraid of a mistyping for "chan", and "chan" appears in the function body
      "read_line chan", so the first check was about the typing implied by the
      read_line function.

      Ciao
      Ernesto
    • oliver@first.in-berlin.de
      ... Wow! Thanks again. The functions first had the names input_header and input_body. Then I renamed them via global search-and-replace to read_header and
      Message 2 of 6 , Mar 13, 2003
      • 0 Attachment
        On Thu, Mar 13, 2003 at 06:46:03PM -0500, Manos Renieris wrote:
        > On Fri, Mar 14, 2003 at 12:33:24AM +0100, oliver@...-berlin.de wrote:
        > > Hello,
        > >
        > > Well there are two basic functions, which read in the
        > > file and create the output data.
        > > One is called input_header, the other is called
        > > input_body.
        > > The problem now is, that they are of input-type unit,
        > > instead of input-type in_channel.
        > >
        > > So instead of in_channel -> string list * string list
        > > they have unit -> string list * string list
        > >
        > > Now here comes the Code:
        > >
        > >
        > > #################################################################
        > > (* Here we have functions to read the mail-header,
        > > the mail-body, and both together *)
        > >
        > > let fl = Stack.create()
        > >
        > >
        > > let input_header chan =
        > > let rec read_lines_helper res =
        > > let sl =
        > > try
        > > Some (Stack.pop fl)
        > > with _ -> begin
        > > try
        > > Some (read_line chan)
        > ^^^^^^^^^
        >
        > read_line has type: unit -> string
        > (it doesn't need a channel, it reads from standard input).
        > The function you need is "input_line".
        >
        > The compiler knows the type of read_line (unit->string)
        > from which it infers that chan must be of type unit.

        Wow!

        Thanks again.

        The functions first had the names input_header and input_body.
        Then I renamed them via global search-and-replace to
        read_header and read_body.
        After the problems I renamed them back by hand, hoping that
        an error will show me the problem...

        ...there was a typing-error/warning, but it didn't show
        me the problem.

        So, thanks.
        I now know, which functions I had renaed too!

        Ciao,
        Oliver
      • oliver@first.in-berlin.de
        ... So I have to look where a function is used the first time in the code? So, when an error occurs, I look for that function and then look for it s first
        Message 3 of 6 , Mar 13, 2003
        • 0 Attachment
          On Fri, Mar 14, 2003 at 01:00:46AM +0100, Stalkern 2 wrote:
          > Il Friday 14 March 2003 00:33, oliver@...-berlin.de ha scritto:
          >
          > [...]
          >
          > > let fl = Stack.create()
          > >
          > >
          > > let input_header chan =
          > > let rec read_lines_helper res =
          > > let sl =
          > > try
          > > Some (Stack.pop fl)
          > > with _ -> begin
          > > try
          > > Some (read_line chan)
          > > with
          > > End_of_file -> None (* no new headers *)
          > > end
          > > in
          > > match sl with
          > > None -> List.rev res
          > > | Some line when String.length line = 0 -> List.rev res (* Header
          > > complete *) | Some l -> read_lines_helper (l :: res) (* prepend new line
          > > *) in
          > > read_lines_helper []
          > >
          >
          > Look:
          >
          > # read_line;;
          > - : unit -> string = <fun>:
          >
          > while you probably want to use
          >
          > # input;;
          > - : in_channel -> string -> int -> int -> int = <fun>
          >
          > with some buffer string as for copying files.
          >
          > If you look at code, generally you see where types are inferred. Here you were
          > afraid of a mistyping for "chan", and "chan" appears in the function body
          > "read_line chan", so the first check was about the typing implied by the
          > read_line function.

          So I have to look where a function is used the first time
          in the code?

          So, when an error occurs, I look for that function
          and then look for it's first occurence?

          Did I understand correctly?

          Ciao,
          Oliver
        • Stalkern 2
          ... No, you have to look where an identifier is casted to a specific type by the type inference mechanism. Type specification (and wrong type specification) if
          Message 4 of 6 , Mar 13, 2003
          • 0 Attachment
            Il Friday 14 March 2003 02:36, oliver@...-berlin.de ha scritto:
            > So I have to look where a function is used the first time
            > in the code?
            >
            > So, when an error occurs, I look for that function
            > and then look for it's first occurence?
            >
            > Did I understand correctly?
            >
            > Ciao,
            > Oliver


            No, you have to look where an identifier is casted to a specific type by the
            type inference mechanism.

            Type specification (and wrong type specification) if any are made
            either by you, with type casting
            # let aFun (aArg:string) = aArg;;
            val aFun : string -> string = <fun>

            or by the type checking mechanism
            # let aFun aArg = aArg;;
            val aFun : 'a -> 'a = <fun>
            # let aNewFun aArg1 =
            let aArg2 = aFun aArg1 in
            print_endline aArg2 (*polymorphism of aArg2 is over*) ;;
            val aNewFun : string -> unit = <fun>

            In your code example, I did not look where "function was used for the first
            time" but "where the polymorphic argument was loosing its polymorphism" (at
            the very beginning, everything is polymorphic: that's maybe why CAML stands
            for *Categorical* Abstract ML).

            A semi-automatic way to detect the same point was to impose your desired type
            by a cast and then let the compiler detect the incoherence . This was
            possible because you knew that chan had to have type in_channel .
            =========================================
            # let fl = Stack.create();;
            val fl : '_a Stack.t = <abstr>

            #let input_header (chan:in_channel) (*type casting here*)=
            let rec read_lines_helper res =
            let sl =
            try
            Some (Stack.pop fl)
            with _ -> begin
            try
            Some (read_line chan)
            with
            End_of_file -> None (* no new headers *)
            end
            in
            match sl with
            None -> List.rev res
            | Some line when String.length line = 0 -> List.rev res (* Header
            complete *)
            | Some l -> read_lines_helper (l :: res) (* prepend new line *)
            in
            read_lines_helper [];;
            val fl : '_a Stack.t = <abstr>
            # Characters 212-216:
            Some (read_line chan)
            ^^^^
            This expression has type in_channel but is here used with type unit
            =========================================
            So you can have Ocaml telling you the weird passage.

            Ernesto
          Your message has been successfully submitted and would be delivered to recipients shortly.