From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail4-relais-sop.national.inria.fr (mail4-relais-sop.national.inria.fr [192.134.164.105]) by sympa.inria.fr (Postfix) with ESMTPS id 3F4277EEAF for ; Fri, 18 Jan 2013 15:15:24 +0100 (CET) Received-SPF: None (mail4-smtp-sop.national.inria.fr: no sender authenticity information available from domain of gabriel.scherer@gmail.com) identity=pra; client-ip=209.85.214.46; receiver=mail4-smtp-sop.national.inria.fr; envelope-from="gabriel.scherer@gmail.com"; x-sender="gabriel.scherer@gmail.com"; x-conformance=sidf_compatible Received-SPF: Pass (mail4-smtp-sop.national.inria.fr: domain of gabriel.scherer@gmail.com designates 209.85.214.46 as permitted sender) identity=mailfrom; client-ip=209.85.214.46; receiver=mail4-smtp-sop.national.inria.fr; envelope-from="gabriel.scherer@gmail.com"; x-sender="gabriel.scherer@gmail.com"; x-conformance=sidf_compatible; x-record-type="v=spf1" Received-SPF: None (mail4-smtp-sop.national.inria.fr: no sender authenticity information available from domain of postmaster@mail-bk0-f46.google.com) identity=helo; client-ip=209.85.214.46; receiver=mail4-smtp-sop.national.inria.fr; envelope-from="gabriel.scherer@gmail.com"; x-sender="postmaster@mail-bk0-f46.google.com"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AvgBANtX+VDRVdYujWdsb2JhbABFFqs4kmIIFg4BAQEBCQkLCRIGI4IeAQEFJxkBGxILAQMMBgULAwoNISIBEQEFAQoSBhMSh3QBAw8MnkqMNIJ7hQwKGScDClmHYQEFDJEtA5YMgRyNTBYphBg X-IronPort-AV: E=Sophos;i="4.84,492,1355094000"; d="scan'208";a="168930032" Received: from mail-bk0-f46.google.com ([209.85.214.46]) by mail4-smtp-sop.national.inria.fr with ESMTP/TLS/RC4-SHA; 18 Jan 2013 15:15:23 +0100 Received: by mail-bk0-f46.google.com with SMTP id q16so2026261bkw.5 for ; Fri, 18 Jan 2013 06:15:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=x-received:mime-version:in-reply-to:references:from:date:message-id :subject:to:cc:content-type; bh=y55WxsEBjwvN3wDBMD5Qsqdexm0y56nM3xer+sOV+D0=; b=nWPpN5Hsh5FlDwTWb1bkBbiZDwvA3gfEuyWYLJiNkE7cdmyPkTdW4FPOUx2jBwjWk3 K3ZBd7SFzLndke7CEvmzfxy3NKMvITFzcV/V38Kjg3gr8tS9ZwdJShCmemYmW/8jCGFw 9OvXtW9wtgrCHJz3Kfmjr2AueNRiRiXgogTKBSZYvqXM2tHVZDAtWyROP3QJoIFHqav4 xqg19SKAHRzvPWr/AxWGeY92Z3BD6+wKX4Yb+jCG5W0wsFUvfhJAeaRH+moE+d1xi4q+ zWjLI3wchqNAPiH9331lGs6DVYkWR6TVZAbyqyG92gLC35uv4HJUFjrK04ApLPu1E7yU joIQ== X-Received: by 10.204.11.78 with SMTP id s14mr2582218bks.118.1358518522869; Fri, 18 Jan 2013 06:15:22 -0800 (PST) MIME-Version: 1.0 Received: by 10.204.236.134 with HTTP; Fri, 18 Jan 2013 06:14:42 -0800 (PST) In-Reply-To: References: <871udjt7e1.fsf@golf.niidar.ru> <87r4ljrogn.fsf@golf.niidar.ru> From: Gabriel Scherer Date: Fri, 18 Jan 2013 15:14:42 +0100 Message-ID: To: Erkki Seppala Cc: caml-list@yquem.inria.fr Content-Type: text/plain; charset=ISO-8859-1 Subject: Re: [Caml-list] Removing repeating code Obj.magic is not part of the OCaml programming language. We should maybe create an unsound-caml-list@inria.fr to let the people using it discuss among themselves! In fact you can *somehow* use GADT (or first-class modules) for related use cases, by using them to represent the type "a array for some a": type some_array = Array : 'a array -> some_array let array = function Strings s -> Array s | Floats s -> Array s This "array" function factorizes the "I don't care which form of array it is" logic. You can then write: let length value = match array value with Array s -> Array.length s (This works well because "Array.length" returns a type that does not mention the type of the array elements; if you use Array.copy here the typer will reject it, because the existential variable would escape. You would need to wrap it again: let copy value = match array value with Array s -> Array (Array.copy s) ) To scale to a richer example with more kind of values, there are three possibilities: (1) Having a partial "array" function that reject non-array values (Using first-class modules for a change) module type Some_array = sig type t val data : t array end let array : value -> (module Some_array) = function | Strings s -> (module (struct type t = string let data = s end)) | Floats s -> (module (struct type t = float let data = s end)) | Int _ -> raise Exit;; let length = function | (Strings _ | Floats _) as v -> let module M = (val (array v)) in Array.length M.data | Int _ -> 1;; (2) Keep arrays under a common constructor (code untested) type value = | VArr of value_array | Int of int and value_array = Strings ... | Floats ... let length = function | Varr v -> let (Array t) = array v in Array.length t | Int -> 1 (3) Use polymorphic variants type value = [ atomic_value | array_value ] and atomic = [ `Int of int ] and array = [ `Strings of ... | `Floats of ... ] let length = function | #atomic_value -> 1 | #array_value as v -> ... All in all, my advice would be to keep the code duplication, which is actually constant-space if you share the common code by definition a polymorphic function as you've done. On Fri, Jan 18, 2013 at 8:08 AM, Erkki Seppala wrote: > > Ivan Gotovchits writes: >> let f = function | Strings a | Floats a -> Array.length a;; >> ^^^^^^^^^^^^^^^^^^^^ >> Error: This pattern matches values of type string array >> but a pattern was expected which matches values of type float array > > Ah, sorry, I completely missed that they were different kind of arrays, > which was of course the point of the example. But as far as I know, > there is no way to remove code duplication in this case, barring tucking > the code 'away' to another function or doing tricks with > Obj.magic. (Well, unless the GADT support brings something to new the > table related to this, but I wouldn't know.) > > -- > _____________________________________________________________________ > / __// /__ ____ __ http://www.modeemi.fi/~flux/\ \ > / /_ / // // /\ \/ / \ / > /_/ /_/ \___/ /_/\_\@modeemi.fi \/ > > -- > Caml-list mailing list. Subscription management and archives: > https://sympa.inria.fr/sympa/arc/caml-list > Beginner's list: http://groups.yahoo.com/group/ocaml_beginners > Bug reports: http://caml.inria.fr/bin/caml-bugs