* [Caml-list] Removing repeating code
@ 2013-01-18 4:57 Ivan Gotovchits
2013-01-18 6:13 ` Erkki Seppala
0 siblings, 1 reply; 5+ messages in thread
From: Ivan Gotovchits @ 2013-01-18 4:57 UTC (permalink / raw)
To: caml-list
Hi!
It was difficult to find a proper phrase for a subject field, sorry. But
in ocaml it is really easier to formulate, so going right to the
question.
Are there any possibility to remove code dublicating in a following
function:
let f = let g = Array.length in function
| Strings a -> g a
| Floats a -> g a
which have a type
val f : value -> int
where value is
type value =
| Strings of string array
| Floats of float array
May be there is some trick?
Thanks in advance!
--
(__)
(oo)
/------\/
/ | ||
* /\---/\
~~ ~~
...."Have you mooed today?"...
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Caml-list] Removing repeating code
2013-01-18 4:57 [Caml-list] Removing repeating code Ivan Gotovchits
@ 2013-01-18 6:13 ` Erkki Seppala
2013-01-18 6:32 ` Ivan Gotovchits
0 siblings, 1 reply; 5+ messages in thread
From: Erkki Seppala @ 2013-01-18 6:13 UTC (permalink / raw)
To: caml-list
Hello,
Ivan Gotovchits <ivg@ieee.org> writes:
> Are there any possibility to remove code dublicating in a following
> function:
>
> let f = let g = Array.length in function
> | Strings a -> g a
> | Floats a -> g a
let f = function | Strings a | Floats a -> Array.length a
Cheers :).
--
_____________________________________________________________________
/ __// /__ ____ __ http://www.modeemi.fi/~flux/\ \
/ /_ / // // /\ \/ / \ /
/_/ /_/ \___/ /_/\_\@modeemi.fi \/
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Caml-list] Removing repeating code
2013-01-18 6:13 ` Erkki Seppala
@ 2013-01-18 6:32 ` Ivan Gotovchits
2013-01-18 7:08 ` Erkki Seppala
0 siblings, 1 reply; 5+ messages in thread
From: Ivan Gotovchits @ 2013-01-18 6:32 UTC (permalink / raw)
To: Erkki Seppala; +Cc: caml-list
Erkki Seppala <flux-caml@inside.org> writes:
> let f = function | Strings a | Floats a -> Array.length a
>
Nope,
# let f = function | Strings a | Floats a -> Array.length a;;
Characters 19-39:
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
Strings a cannot be unified with Floats a ...
--
(__)
(oo)
/------\/
/ | ||
* /\---/\
~~ ~~
...."Have you mooed today?"...
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Caml-list] Removing repeating code
2013-01-18 6:32 ` Ivan Gotovchits
@ 2013-01-18 7:08 ` Erkki Seppala
2013-01-18 14:14 ` Gabriel Scherer
0 siblings, 1 reply; 5+ messages in thread
From: Erkki Seppala @ 2013-01-18 7:08 UTC (permalink / raw)
To: caml-list
Ivan Gotovchits <ivg@ieee.org> 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 \/
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Caml-list] Removing repeating code
2013-01-18 7:08 ` Erkki Seppala
@ 2013-01-18 14:14 ` Gabriel Scherer
0 siblings, 0 replies; 5+ messages in thread
From: Gabriel Scherer @ 2013-01-18 14:14 UTC (permalink / raw)
To: Erkki Seppala; +Cc: caml-list
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 <flux-caml@inside.org> wrote:
>
> Ivan Gotovchits <ivg@ieee.org> 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
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2013-01-18 14:15 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-01-18 4:57 [Caml-list] Removing repeating code Ivan Gotovchits
2013-01-18 6:13 ` Erkki Seppala
2013-01-18 6:32 ` Ivan Gotovchits
2013-01-18 7:08 ` Erkki Seppala
2013-01-18 14:14 ` Gabriel Scherer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox