From: Arnaud Spiwack <Arnaud.Spiwack@lix.polytechnique.fr>
To: OCaml Mailing List <caml-list@inria.fr>
Subject: Re: [Caml-list] One-value functors
Date: Mon, 21 May 2012 11:25:29 +0200 [thread overview]
Message-ID: <CAMoPVjcTRLQzPm09PxLUFvaGWBgG+Spvd6=JJJH590NNe=cRDQ@mail.gmail.com> (raw)
In-Reply-To: <CA+qp_4qiEQDiEhotX8dY1esLVeXqjorttW9EJLWvWUqmeaXTRQ@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 3517 bytes --]
On 17 May 2012 18:23, Nicolas Braud-Santoni <nicolas@braud-santoni.eu>wrote:
> Hi,
>
> If I'm not mistaken, you want something like Haskell's typeclasses.
> I agree that it's a feature I often find myself wanting in OCaml, and
> -as you point out- is trivial to encode with module and functors, so
> it shouldn't be highly problematic.
>
Well, there is a superficial similarity with typeclasses, in that it may be
used for similar patterns, and that without first-class functors, we are
bound to some prefix abstractions (first all the functor abstractions, then
the regular type). With first-class functors, however, we can, in principle
be much freer. But really, my reason for using these one-value functors
(monofunctors?) is to gain access to higher kinding (like, in my above
example, function abstracted over type families).
On 17 May 2012 16:52, Goswin von Brederlow <goswin-v-b@web.de> wrote:
> Arnaud Spiwack <Arnaud.Spiwack@lix.polytechnique.fr> writes:
> > type a and b
> > module type TC = sig type 'a t end
> > module type Subst = functor (A:TC) -> sig val x : a A.t -> b A.t end
>
> What are you trying to do there? Why do you need a functor for that at
> all? TC just having a type doesn't make sense to me.
>
This is part of the definition of Leibniz equality in [
http://okmij.org/ftp/ML/first-class-modules/first-class-modules.pdf ]. The
idea is that a and b must be the same type et Subst.x the identity.
Hard to say if I can't even understand what "this kind of thing" is.
>
Well, you probably never needed such a pattern, otherwise you would have
recognised it. Let me try to give you a more concrete example.
The simplest case, I believe, where one would want higher-kinding is linked
to interruptible List.fold_left, using option to report errors (you can use
it, for instance, to define List.for_all exiting as soon as you know the
answer is "false"). Let's proceed :
val i_iter : ('a -> 'b -> 'a option) -> 'a -> 'b list -> 'a option
let rec i_iter f seed = function
| [] -> Some seed
| b::l -> match f seed b with | None -> None | Some a -> i_iter f a l
This was quite direct, but is part of a bigger story, which involves
monads. The above definition can be abstracted over monads in the following
manner
module type Monad = sig
type 'a t
val return : 'a -> 'a t
val (>>=) : 'a t -> ('a -> 'b t) -> 'b t
end
module MIter (M:Monad) = struct
let rec x f seed = function
| [] -> M.return seed
| b::l -> M.(f seed b >>= fun a -> x f a l)
end
The proposed syntax would let me write the MIter as a val, rather than a
module :
val m_iter : (M:Monad) => ('a -> 'b -> 'a M.t) -> 'a -> 'b list -> 'a M.t
Then you can get the traditional fold_left as
let fold_left = m_iter {{struct type 'a t = 'a let return x = x let (>>=)
x k = k x end}}
The interruptible fold_left as
let i_iter = m_iter {{struct type 'a t = 'a option let return x = Some x
let (>>=) x k = match x with | None -> None | Some x' -> k x' end}}
You can also get a lazy fold_left as
let l_iter = m_iter {{struct type 'a t = 'a Lazy.t let return x =
Lazy.lazy_from_val x let (>>=) x k = lazy (k (force x)) end}}
One that is particularly useful for me is a fold_left compatible with state
passing style
let s_iter (type state) = m_iter {{struct type 'a t = state -> ('a*state)
let return x s = (x,s) let (>>=) x k s = let (x',s') = x s in k x' s' end}}
What matters is that I need to abstract over a type family, which cannot be
done without functors in OCaml.
--
Arnaud
[-- Attachment #2: Type: text/html, Size: 5170 bytes --]
next prev parent reply other threads:[~2012-05-21 9:26 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-05-11 10:03 Arnaud Spiwack
2012-05-17 14:52 ` Goswin von Brederlow
2012-05-17 16:23 ` Nicolas Braud-Santoni
2012-05-21 9:25 ` Arnaud Spiwack [this message]
2012-05-30 14:14 ` Arnaud Spiwack
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CAMoPVjcTRLQzPm09PxLUFvaGWBgG+Spvd6=JJJH590NNe=cRDQ@mail.gmail.com' \
--to=arnaud.spiwack@lix.polytechnique.fr \
--cc=caml-list@inria.fr \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox