-
Notifications
You must be signed in to change notification settings - Fork 12
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
Add explicitly bidirectional pattern synonyms for certain structs #34
Comments
Hmm, that might work. There is a problem that some structs are rather big and have many optional fields (which default to |
I agree that it wouldn't be very useful for the large structs where one usually wants to access a single field. Does the matching force reading all the fields? Adding a trace statement: {-# COMPLETE VkSurfaceFormatKHR #-}
pattern VkSurfaceFormatKHR :: VkFormat -> VkColorSpaceKHR -> VkSurfaceFormatKHR
pattern VkSurfaceFormatKHR fmt spc
<- ( getField @"format" &&& ( getField @"colorSpace" . trace "reading colorSpace" )
-> (fmt, spc)
)
where VkSurfaceFormatKHR fmt spc
= createVk ( set @"format" fmt &* set @"colorSpace" spc )
testSurfaceFormat :: VkSurfaceFormatKHR
testSurfaceFormat
= VkSurfaceFormatKHR VK_FORMAT_R8G8B8A8_UNORM VK_COLOR_SPACE_SRGB_NONLINEAR_KHR > let VkSurfaceFormatKHR fmt col = testSurfaceFormat
> fmt
VK_FORMAT_R8G8B8A8_UNORM
> col
reading colorSpace
VK_COLOR_SPACE_SRGB_NONLINEAR_KHR We don't even need to do a lazy pattern match, either in the definition of the pattern or at its use-site. Please correct me if I am missing a subtlety about |
Note that you can also use record syntax for pattern synonyms, which may be even nicer. |
That's, nice, I didn't know about that. To spell out the obvious, if we write {-# COMPLETE VkSurfaceFormatKHR #-}
pattern VkSurfaceFormatKHR :: VkFormat -> VkColorSpaceKHR -> VkSurfaceFormatKHR
pattern VkSurfaceFormatKHR { format, colorSpace }
<- ( getField @"format" &&& getField @"colorSpace" -> ( format, colorSpace ) )
where VkSurfaceFormatKHR fmt spc
= createVk ( set @"format" fmt &* set @"colorSpace" spc ) then we can use record syntax as we'd usually do: surfaceFormat :: VkSurfaceFormatKHR
surfaceFormat
= VkSurfaceFormatKHR
{ colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR
, format = VK_FORMAT_R8G8B8A8_UNORM
}
> format surfaceFormat
VK_FORMAT_R8G8B8A8_UNORM
> colorSpace surfaceFormat
VK_COLOR_SPACE_SRGB_NONLINEAR_KHR We can even define a |
@sheaf yes, you are right! With Wow, I did not really know that record syntax is supported in synonyms! Is it available since long ago? And btw, what is the status of duplicate/overloaded field extensions? We would really need these. |
Seems it was part of GHC 8.0, see GHC issue #8582. Concerning duplicate record fields I came across ticket #11228, and ticket #14630 also has some interesting discussion on the topic. |
@sheaf thanks for the links! I have tried to use duplicate records in Another thing that puzzles me is whether updating structs this way via records is going to be a considerable performance problem. Updating just one field in a struct would mean to read all its fields one by one, to create new byte array, and to write all the fields in there. A lot of overhead for something so cheap in the usual Haskell! |
Thanks to ZuriHac 2019, I've got an idea for a possible solution: |
Instead of always using
getField
andset
, I believe some non-opaque struct types could benefit from using explicitly bidirectional pattern synonyms. For instance:The text was updated successfully, but these errors were encountered: