I'm looking to model logging outputs for a user library. The easiest approach would be a sum type with all the data I need:
data LogOutput
= File Text
| Console
However I want the user 1) to be able to make their own output 2) work with any number of outputs at run time. This was beginning to look like a good fit for data/type families, but I'm having trouble with desire 2. Is a list of data families possible or would another approach be more suitable?
A small example
data family LogOutput a
data Console = Console Bool
deriving stock Show
data instance LogOutput Console = LogOutputConsole
deriving stock Show
data File = File Text
data instance LogOutput File = LogOutputFile Int
type LogOutputs a = [LogOutput a]
main = do
let l = LogOutputConsole
l2 = LogOutputFile 1
print l
let ls = [l, l2 ]
print ls
Produces an expected error
play.hs:75:16: error:
• Couldn't match type ‘File’ with ‘Console’
Expected type: LogOutput Console
Actual type: LogOutput File
• In the expression: l2
In the expression: [l, l2]
In an equation for ‘ls’: ls = [l, l2]
|
75 | let ls = [l, l2 ]
| ^^
Duh! The Custom a actually does make things simple. However I still need something like hlist to handle a list of outputs for the case when a user has 2 different Custom outputs
I'm looking to model logging outputs for a user library. The easiest approach would be a sum type with all the data I need:
However I want the user 1) to be able to make their own output 2) work with any number of outputs at run time. This was beginning to look like a good fit for data/type families, but I'm having trouble with desire 2. Is a list of data families possible or would another approach be more suitable?
A small example
Produces an expected error
not quite sure what you're intending to do with that
Int
but I suspect that the best way to start would besounds like you need an open union to me :thinking:
https://hackage.haskell.org/package/fastsum
https://hackage.haskell.org/package/open-union
https://hackage.haskell.org/package/world-peace
tho I haven't actually used any of them
why?
actually I guess with the
| Custom a
approach the user can then use an open union themselves for thea
but I, for some reason, assumed Adam wants this built into the library
still, what's the motivation for the open union?
so that the user can insert as many different "logging types" as they want
without having to add an open union impl. themselves
it could be wrapped in a nice interface that doesn't mention the underlying open union implementation at all
what would the semantics of that be? you would have specialized logging types for individual subprograms?
ok, I agree, there's no point usually, the user can just define their own sum type of things they want to log
because usually you know what you're logging statically*
it doesn't sound unreasonable to me if you have many logging types
but it seems unlikely that you would have many logging types!
I guess if you want to restrict where you can log what using type signatures it might also be useful
Duh! The
Custom a
actually does make things simple. However I still need something likehlist
to handle a list of outputs for the case when a user has 2 differentCustom
outputsI would assume that your user would supply a handler function for their
Custom a
to your api function. ifa
is a sum type, they can just match on that