<div dir="auto"><div>I agree with Andrew, let's just export the lifted ffi call<div dir="auto"><br></div><div dir="auto">This suits my needs, but, regardless of my needs, seems like a perfectly sensible addition to Foreign.C.String</div><div dir="auto"><br></div><div dir="auto">Concrete addition:</div><div dir="auto"><br></div><div dir="auto">foreign import unsafe "strlen"</div><div dir="auto">  cstringLength :: CString -> IO Int</div><br><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Jan 22, 2021, 17:09 Viktor Dukhovni <<a href="mailto:ietf-dane@dukhovni.org">ietf-dane@dukhovni.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Fri, Jan 22, 2021 at 04:56:33PM -0500, Andrew Martin wrote:<br>
<br>
> This will eventually be used to great effect in bytestring. See<br>
> <a href="https://github.com/haskell/bytestring/pull/191" rel="noreferrer noreferrer" target="_blank">https://github.com/haskell/bytestring/pull/191</a>.<br>
<br>
Yes, you might recall that I'm well aware of that (already merged) PR,<br>
indeed that's how I happened to recall that cstringLength# is present<br>
in 9.0.<br>
<br>
> To get back to the original question, I think that any user-facing<br>
> cstringLength function should probably be:<br>
> <br>
>     cstringLength :: CString -> IO Int<br>
> <br>
> We need a separate FFI call that returns its result in IO to<br>
> accomplish this. But this just be done in base rather than ghc-prim.<br>
> There are no interesting rewrite rules that exist for such a function.<br>
<br>
So I guess your suggestion in response to @chessai's original post:<br>
<br>
>> On Wed, Jan 20, 2021 at 09:54:30AM -0800, chessai wrote:<br>
>> <br>
>> I've wanted the following before:<br>
>> <br>
>> foreign import ccall unsafe "strlen"<br>
>>   cstringLength# :: Addr# -> Int#<br>
>> <br>
>> cstringLength :: CString -> Int<br>
>> cstringLength (Ptr s) = I# (cstringLength# s)<br>
>> <br>
>> A natural place for this seems to be Foreign.C.String.<br>
<br>
would be to instead directly implement the lifted FFI variant:<br>
<br>
    foreign import ccall unsafe "strlen"<br>
      cstringLength :: CString -> IO Int<br>
<br>
which probably would not need a wrapper and can be exported directly.<br>
<br>
    module Main (main) where<br>
    import Control.Monad ( (>=>) )<br>
    import Foreign.C.String (CString, withCString)<br>
<br>
    foreign import ccall unsafe "strlen"<br>
      cstringLength :: CString -> IO Int<br>
<br>
    main :: IO ()<br>
    main = withCString "Hello, World!" $ cstringLength >=> print<br>
<br>
The cost of this safety net is that it results in more sequencing than<br>
is strictly necessary.  It is enough for the enclosing IO action to not<br>
embed the length in its result in some not yet fully evaluated thunk.<br>
<br>
I guess @chessai can let us know whether the more strictly sequenced<br>
variant meets his needs.<br>
<br>
-- <br>
    Viktor.<br>
_______________________________________________<br>
Libraries mailing list<br>
<a href="mailto:Libraries@haskell.org" target="_blank" rel="noreferrer">Libraries@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" rel="noreferrer noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries</a><br>
</blockquote></div></div></div>