Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Varargs version to avoid needing ! #36

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

aavogt
Copy link

@aavogt aavogt commented Jan 29, 2023

Maybe this should be exported from Named instead? Or Named.Varargs should reexport the needed parts of Named?

I would also like the equivalent of these two functions: R's ... extra arguments and R's do.call. Maybe we don't need an intermediate hlist of extra arguments. If the function wants a va_list, perhaps withs could accept extra arguments and supply a function that applies them. In other words, I'm proposing that the following would print '3'

main = print $ withs f #x 2 End
f (arg #va_list -> g) = g h
h (arg #x -> x) = x+1

@int-index
Copy link
Contributor

Hi, this looks interesting, but it's not clear to me why you want to avoid !

@aavogt
Copy link
Author

aavogt commented Jan 29, 2023

I think the difference is small. I am making a wrapper to void ImGui_ShowDemoWindow(bool* p_open /* = NULL */);. It is usually called with NULL. Here are my options from least to most pleasant at the call site:

-- Maybe
showDemoWindow Nothing
showDemoWindow (Just p)

-- Named
showDemoWindow ! defaults
showDemoWindow ! #p_open p

-- two functions
showDemoWindow
showDemoWindow_ p

-- Named.Varargs
showDemoWindow ()
showDemoWindow #p_open p ()

-- two instances
showDemoWindow
showDemoWindow p

The instances are written like:

class ShowDemoWindow a where
 showDemoWindow :: a
instance a ~ () => ShowDemoWindow (IO a) where showDemoWindowClass = raw_showDemoWindow nullPtr
instance (a ~ Ptr CUChar, b ~ IO ()) => ShowDemoWindow (a -> b) where showDemoWindow = raw_showDemoWindow

The "two instances" looks ideal, but I don't think it scales to multiple arguments. It doesn't need the () / End argument because it commits to producing something in IO, which might rule out having liftIO pre-applied to these functions. Also I want consistency between the 1 and 5 argument functions, plus the instances have more code and make type errors worse.

@int-index
Copy link
Contributor

Thank you for explaining your use case. What about the type signature that showDemoWindow gets? With the !-based approach, the type would be

showDemoWindow :: "p_open" :? Ptr CUChar -> IO ()

This is fairly straightforward to understand, there aren’t any type classes in the signature. I wouldn’t want to adopt an approach that adds more complexity to type signatures (e.g. any type variables or constraints).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants