Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Safe alternative to partial records?

Tags:

haskell

I'm trying to figure out a reasonable way to let users of my library supply me with a bunch of functions to control the way it behaves. I'd like to supply them with some defaults they can combine and override as they see fit. The obvious way (to me) is just a record of functions like Foo {a, b, c, d, e} and make it a monoid and then provide some default values they can mappend together. But the defaults I make wouldn't provide all the functions. So I might have a record with {a, b} and one with {c, d} and another with {b, c, e}. That obviously isn't safe, and a user could supply me with a record like {a, b, c, e} which would be bad. I want the user to be able to mix and match pieces like that, but still have to end up with a complete record.

Is there a safe way to do something like this? If I made all the functions in the record into Maybe functions then I am at least making it so I can check if the supplied value is missing a function, but then they are still getting that error at runtime instead of compile time. I would much rather have the "all fields in the record must be provided" invariant enforced by the compiler if I can.

like image 283
user3261399 Avatar asked May 05 '14 04:05

user3261399


1 Answers

You are looking for data-default package. Using this, you can safely initialize the default values for your types. Example:

import Data.Default

data Foo = Foo { a :: Int, b :: Int }

instance Default Foo where
  def = Foo 3 3

Now using def you can use the default value in any function you need:

dummyFun :: Foo -> Foo
dummyFun x = def

You can also change the record value as required by you:

dummyFun :: Foo -> Foo
dummyFun x = def { b = 8 }
like image 69
Sibi Avatar answered Oct 28 '22 13:10

Sibi