<div dir="ltr"><div>I'm the author of the instance [1].</div><div><br></div><div>One of my libraries uses Storable vectors to represent buffers of audio samples[1]. When the user doesn't need input, they leave the type of input vector to be `Vector ()`,</div><div>which is totally valid and reasonable under the constraint that the input buffer and the output buffer have the same size.</div><div><br></div><div>> 
This means that we can read an infinite number of ()<br>
type values out of nothing (no memory location required) or store an<br>
infinite number of () type values without even requiring a memory<br>
location to write to. <br></div><div><br></div><div>Yes, we can read an infinite number of () without reading anything in memory. That's intended, and it is less arbitrary than defining () as a single byte object.<br></div><div><br></div><div>Perhaps you may want to reconsider the design of your array implementation before roasting this instance as "broken" and "absurd".<br></div><div><br></div><div>[1] <a href="https://gitlab.haskell.org/ghc/ghc/-/commit/97843d0b10cac3912a85329ebcb8ed1a68f71b34">https://gitlab.haskell.org/ghc/ghc/-/commit/97843d0b10cac3912a85329ebcb8ed1a68f71b34</a></div><div>[2] <a href="https://github.com/fumieval/bindings-portaudio/blob/4e49c50d19d141062e7a75a5e39d8c8388456309/System/PortAudio.hs#L252">https://github.com/fumieval/bindings-portaudio/blob/4e49c50d19d141062e7a75a5e39d8c8388456309/System/PortAudio.hs#L252</a></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">2022年1月5日(水) 17:01 Harendra Kumar <<a href="mailto:harendra.kumar@gmail.com">harendra.kumar@gmail.com</a>>:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">The Storable instance of () is defined in the "Foreign.Storable"<br>
module of the "base" package as follows:<br>
<br>
instance Storable () where<br>
  sizeOf _ = 0<br>
  alignment _ = 1<br>
  peek _ = return ()<br>
  poke _ _ = return ()<br>
<br>
The size of () is defined as 0. It sounds absurd for a Storable to<br>
have a size of 0? This means that we can read an infinite number of ()<br>
type values out of nothing (no memory location required) or store an<br>
infinite number of () type values without even requiring a memory<br>
location to write to.<br>
<br>
This is causing a practical problem in our Storable array<br>
implementation. The array is constrained to a Storable type. Since ()<br>
has a Storable instance, one can store () in the Storable array. But<br>
it causes a problem because we determine the array element size using<br>
sizeOf on the type. For () type it turns out to be 0. Essentially, the<br>
array of () would always be of size 0. Now, we cannot determine the<br>
length of the array from its byte length as you could store infinite<br>
such elements in an empty array. The Storable instance of () seems to<br>
be an oddity and makes us use a special case everywhere in the code to<br>
handle this, and this special casing makes it highly prone to errors<br>
when we change code.<br>
<br>
Can this be fixed? Is there a compelling argument to keep it like<br>
this? A possible fix could be to represent it by a single byte in<br>
memory which can be discarded when reading or writing. Another<br>
alternative is to not provide a Storable instance for it at all. Let<br>
the users write their own if they need it.<br>
<br>
If you think this does not have a problem, can you suggest how to<br>
elegantly handle the array implementation problem as I described<br>
above?<br>
<br>
Thanks,<br>
Harendra<br>
_______________________________________________<br>
Libraries mailing list<br>
<a href="mailto:Libraries@haskell.org" target="_blank">Libraries@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries</a><br>
</blockquote></div>