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

Re: "ocaml_beginners"::[] why is the :: operator so special?

Expand Messages
  • darooha
    Well, the syntax is completely different inside pattern matching. For example, you can write expressions involving _ inside the match expressions, but not
    Message 1 of 5 , Oct 1, 2011
    • 0 Attachment
      Well, the syntax is completely different inside pattern matching. For example, you can write expressions involving _ inside the match expressions, but not outside etc. So I don't consider this to be a particularly enlightening answer. But thanks anyway. :-)

      The reason this came up is because I wrote a nifty little loop template:

      let rec fold i j f init = if i>j then init else fold (i+1) j f (f i init)

      Then I can use it like this:

      # fold 1 10 (+) 0;;
      - : int = 55

      # fold 1 10 ( * ) 1;;
      - : int = 3628800

      # fold 1 10 (fun a b -> a::b) [];;
      - : int list = [10; 9; 8; 7; 6; 5; 4; 3; 2; 1]

      But I wanted to write "(::)" instead of (fun a b -> a::b). But I couldn't.




      --- In ocaml_beginners@yahoogroups.com, Sebastien Mondet <sebastien.mondet@...> wrote:
      >
      > The (::) has a particular status in the syntax so that we can use it inside
      > pattern matching:
      >
      > match l with
      > | [] -> stuff
      > | h :: t -> other_stuff
      >
      > It is not a function it is like a constructor for the type list.
      >
      >
      >
      >
      >
      > On Fri, Sep 30, 2011 at 09:30, darooha <sleator@...> wrote:
      >
      > > I can write "(+)" to indicate the function that adds its two arguments. I
      > > can do this for any infix operator except one. It does not work for the
      > > cons operator on lists. So I can't write "(::)".
      > >
      > > So my questions are: (1) Why this bizarre inconsistency in the language?
      > > (2) other than writing (fun a b -> a::b) how to I access this operator.
      > > It's not called "List.cons" Does it have some other name?
      > >
      > > Thanks.
      > >
      > > Danny Sleator
      > >
      > >
      > >
      > >
      > > ------------------------------------
      > >
      > > Archives up to December 31, 2010 are also downloadable at
      > > http://www.connettivo.net/cntprojects/ocaml_beginners
      > > The archives of the very official ocaml list (the seniors' one) can be
      > > found at http://caml.inria.fr
      > > Attachments are banned and you're asked to be polite, avoid flames
      > > etc.Yahoo! Groups Links
      > >
      > >
      > >
      > >
      >
      >
      > [Non-text portions of this message have been removed]
      >
    • Gabriel Scherer
      (::) is considered a constructor, not a function. This is why it can be used both in expressions and in patterns, but, in an expression, cannot be used as a
      Message 2 of 5 , Oct 1, 2011
      • 0 Attachment
        (::) is considered a constructor, not a function. This is why it can
        be used both in expressions and in patterns, but, in an expression,
        cannot be used as a non-applied function. The same thing applies to
        other constructors:

        # type 'a option = None | Some of 'a;;
        type 'a option = None | Some of 'a
        # Some;;
        Error: The constructor Some expects 1 argument(s),
        but is applied here to 0 argument(s)
        # (fun x -> Some x);;
        - : 'a -> 'a option = <fun>

        The difference between (::) and other constructors (but `()`, the
        value of type `unit`) is that it is in a infix form. Contrarily to
        functions, for which infix are cleanly defined in the OCaml syntax and
        can be created by the user (let (++) a b = ...), infix *constructors*
        are special, hard-coded into the syntax. (::) would not be a legal
        infix function name anyway, as you can check on the manual page
        describing the infix symbols grammar :
        http://caml.inria.fr/pub/docs/manual-ocaml/lex.html#infix-symbol

        As a gory detail and horror story, note that it is actually possible
        to use those two special constructors in user-defined algebraic
        datatypes. This is in no way allowed by the OCaml language
        specification, may change in further versions and not be supported by
        alternative parsers such as camlp4, so you should *not* use it, but
        just for fun:

        # type 'a weird = () | :: of 'a weird * 'a weird;;
        type 'a weird = () | :: of 'a weird * 'a weird
        # (() :: ()) :: ();;
        - : 'a weird = :: (:: ((), ()), ())

        (It doesn't work to use `[]` here; apparently [...; ...; ...] is
        defined independently as syntactic sugars, rather)

        More funny undefined parser behavior ?

        # begin end;;
        'a weird = ()

        On Sat, Oct 1, 2011 at 3:55 PM, darooha <sleator@...> wrote:
        > Well, the syntax is completely different inside pattern matching.  For example, you can write expressions involving _ inside the match expressions, but not outside etc.  So I don't consider this to be a particularly enlightening answer.  But thanks anyway.  :-)
        >
        > The reason this came up is because I wrote a nifty little loop template:
        >
        > let rec fold i j f init = if i>j then init else fold (i+1) j f (f i init)
        >
        > Then I can use it like this:
        >
        > # fold 1 10 (+) 0;;
        > - : int = 55
        >
        > # fold 1 10 ( * ) 1;;
        > - : int = 3628800
        >
        > # fold 1 10 (fun a b -> a::b) [];;
        > - : int list = [10; 9; 8; 7; 6; 5; 4; 3; 2; 1]
        >
        > But I wanted to write "(::)" instead of (fun a b -> a::b). But I couldn't.
        >
        >
        >
        >
        > --- In ocaml_beginners@yahoogroups.com, Sebastien Mondet <sebastien.mondet@...> wrote:
        >>
        >> The (::) has a particular status in the syntax so that we can use it inside
        >> pattern matching:
        >>
        >> match l with
        >> | [] -> stuff
        >> | h :: t -> other_stuff
        >>
        >> It is not a function it is like a constructor for the type list.
        >>
        >>
        >>
        >>
        >>
        >> On Fri, Sep 30, 2011 at 09:30, darooha <sleator@...> wrote:
        >>
        >> > I can write "(+)" to indicate the function that adds its two arguments.  I
        >> > can do this for any infix operator except one.  It does not work for the
        >> > cons operator on lists.  So I can't write "(::)".
        >> >
        >> > So my questions are:  (1) Why this bizarre inconsistency in the language?
        >> >  (2) other than writing (fun a b -> a::b) how to I access this operator.
        >> >  It's not called "List.cons" Does it have some other name?
        >> >
        >> > Thanks.
        >> >
        >> >               Danny Sleator
        >> >
        >> >
        >> >
        >> >
        >> > ------------------------------------
        >> >
        >> > Archives up to December 31, 2010 are also downloadable at
        >> > http://www.connettivo.net/cntprojects/ocaml_beginners
        >> > The archives of the very official ocaml list (the seniors' one) can be
        >> > found at http://caml.inria.fr
        >> > Attachments are banned and you're asked to be polite, avoid flames
        >> > etc.Yahoo! Groups Links
        >> >
        >> >
        >> >
        >> >
        >>
        >>
        >> [Non-text portions of this message have been removed]
        >>
        >
        >
        >
        >
        > ------------------------------------
        >
        > Archives up to December 31, 2010 are also downloadable at http://www.connettivo.net/cntprojects/ocaml_beginners
        > The archives of the very official ocaml list (the seniors' one) can be found at http://caml.inria.fr
        > Attachments are banned and you're asked to be polite, avoid flames etc.Yahoo! Groups Links
        >
        >
        >
        >
      Your message has been successfully submitted and would be delivered to recipients shortly.