From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.1.3 (2006-06-01) on yquem.inria.fr X-Spam-Level: * X-Spam-Status: No, score=2.0 required=5.0 tests=AWL,DNS_FROM_RFC_POST, SPF_NEUTRAL autolearn=disabled version=3.1.3 X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from mail1-relais-roc.national.inria.fr (mail1-relais-roc.national.inria.fr [192.134.164.82]) by yquem.inria.fr (Postfix) with ESMTP id 0828DBBC4 for ; Wed, 4 Mar 2009 22:44:59 +0100 (CET) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AigCAPCErknRVduukWdsb2JhbACURD8BAQEBCQkMBw+yAYEHkCwBAwEDhAUGgn0 X-IronPort-AV: E=Sophos;i="4.38,303,1233529200"; d="scan'208";a="25078030" Received: from mail-ew0-f174.google.com ([209.85.219.174]) by mail1-smtp-roc.national.inria.fr with ESMTP; 04 Mar 2009 22:44:58 +0100 Received: by ewy22 with SMTP id 22so2912185ewy.27 for ; Wed, 04 Mar 2009 13:44:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:content-type:cc:subject:from :to:references:in-reply-to:date:message-id:user-agent; bh=AVqEq0TYeHiJIDzGD7IDy8nr0eYTAHMKmHO3YYIdGmQ=; b=iENrEDBzyMTrIH1ghVTeRZsnYKp4Zj33vY5dxnvwHqxypGUCyjSYojJiutMhKqCxO0 pVU6APrB2z/mtFrBUm3US6h634lrlDihjYKge1va3mX6KH/7nTUedISTL+pJD+ajP8I7 6Mb/NSPWN8NEXBd49ZvSIlGS6sHHo6TGA6IMY= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=content-type:cc:subject:from:to:references:in-reply-to:date :message-id:user-agent; b=PjNAZ6iymWlv2hRzJDkSceA+/mQvn843psDNTi/9tp4No+5BggbnvC+S8Ji0646xob 5sqd8cA/JVHUlJ+NUdC3Gl59Du3H5Ldpw0MejyF21il/Sy/FI1mcxZ2Th6R4uNSZEHDq DMyWgffxO2fn6d7MMYY+SvoMSmSskzNvAI7qs= Received: by 10.210.126.18 with SMTP id y18mr260798ebc.5.1236203097613; Wed, 04 Mar 2009 13:44:57 -0800 (PST) Received: from localhost (home.feydakins.org [82.229.164.236]) by mx.google.com with ESMTPS id 2sm6945926nfv.48.2009.03.04.13.44.54 (version=TLSv1/SSLv3 cipher=RC4-MD5); Wed, 04 Mar 2009 13:44:55 -0800 (PST) Content-Type: text/plain; charset=UTF-8 Cc: Peng Zang , Jon Harrop , caml-list Subject: Re: [Caml-list] stl? From: Nicolas Pouillard To: Brian Hurt References: <91a2ba3e0903031340wcdc976cp52522eb35f7ccb73@mail.gmail.com> <200903040159.48574.jon@ffconsultancy.com> <200903040920.01990.peng.zang@gmail.com> In-Reply-To: Date: Wed, 04 Mar 2009 22:43:48 +0100 Message-Id: <1236200892-sup-9751@ausone.local> User-Agent: Sup/git X-Spam: no; 0.00; stl:01 hash:01 functors:01 functorize:01 functorizing:01 functors:01 haskell:01 checker:01 haskell:01 runtime:01 accessor:01 functor:01 ord:01 ord:01 enum:01 Excerpts from Brian Hurt's message of Wed Mar 04 17:14:50 +0100 2009: > > > On Wed, 4 Mar 2009, Peng Zang wrote: > > > -----BEGIN PGP SIGNED MESSAGE----- > > Hash: SHA1 > > > > On Wednesday 04 March 2009 01:11:18 am Brian Hurt wrote: [...] > > But I'll add one more reason. With functors you have extra overhead like > > having to be explicit with what function you're using. In your example when > > you want to use Newton's method you always must write "RatioNewton.newtons" > > or "FloatNewtons.newtons". The alternative is to functorize the call site, > > but (1) that has its own cost: lots of boilerplate functorizing code crowding > > the real code and (2) you just defer the explicit naming cost as when that > > function is called you'll still have to call either Float version or Ratio > > version. > > Yeah. I think of this as one of the advantages of Functors. > > Here are two real problems I've hit with type classes, in only a few weeks > banging around in Haskell. > > For example, you can't have more than one instance of a type class for any > given type. So let's say you want to have a type class for things that > can be converted to and from s-expressions, like: [...] > Now, I comment you *can* do this in Haskell- using GHC specific > extensions. But you don't need fancy extensions (which cause problems in > the type checker, if I understand things correctly) to do this, quite > easily, with functors. Haskell `newtype's is a pretty reasonable answer to this problem. A `newtype' is a bit like a type with only one constructor of only one argument, except that there is no runtime cost for it. However by being a *new* type one can define different instances of type classes for it. Moreover since the deriving feature is extended on `newtype's, retrieving all the goodness of the wrapped type is costless (deriving newtype is easy since generally the code justs virtually unpacks and re-packs using the constructor and call the same functions on the wrapped value). Examples: \begin{code} {-# LANGUAGE GeneralizedNewtypeDeriving #-} import Data.List import Data.Function newtype MySet a = MkMySet { toList :: [a] } -- here toList is an accessor -- function (MySet a -> [a]) deriving (Read,Show,Functor,Monad) -- ... norm :: Ord a => MySet a -> [a] norm = nub . sort . toList instance (Ord a) => Eq (MySet a) where (==) = (==) `on` norm instance (Ord a) => Ord (MySet a) where compare = compare `on` norm propMySet = MkMySet [1,2,3,4] == MkMySet [1,1,2,4,3] \end{code} Or another one: \begin{code} newtype DownInt = DownInt { fromDownInt :: Int } deriving (Eq,Read,Show,Enum,Num) instance Ord DownInt where compare = flip compare `on` fromDownInt -- same as compare x y = fromDownInt y `compare` fromDownInt x propDownInt = DownInt 4 < DownInt 2 -- this example is contrived since sortBy would be simpler here -- however in larger examples the benifit is clearer, for instance -- List.sort is not in a functor in OCaml. sortDownInt :: [Int] -> [Int] sortDownInt = map fromDownInt . sort . map DownInt propDownInt' = [4,3,2,1] == sortDownInt [1,2,3,4] -- since DownInt is in the Num class (an explicit choice -- from the definition of DownInt), literals can be -- freely lifted to DownInt. propDownInt'' = [4,3,2,1] == sort [(1::DownInt),2,3,4] \end{code} Note that one can generalize `DownInt' as `Down' and get an easy way to reverse the order on a type. Since that, I personally consider type-classes goodness more valuable than functors usage that doesn't fall in that category. All the best, -- Nicolas Pouillard