Haskell way of defining and implementing OO interfaces

Hi, I'm writing a password manager that implements a dbus-api using the dbus[1] package. I'd like to separate the code that implements from the dbus api from the code that stores and retrieves the secrets (passwords). In Java I'd use an interface, e.g.: interface PasswordStore { void store(Path path, String secret, Map metadata); (String secret, Map metadata) retrieve(Path path); (String secret, Map metadata) search(Map criteria); } And the dbus-api would export this interface: dbusClient.export(PasswordStore store) What would be a Haskell way to do the same? My only idea is to define a record: data PasswordStore { store :: Path -> Secret -> MetaData -> IO () , retrieve :: Path -> IO (Secret, MetaData) , search :: Criteria -> IO (Secret, MetaData) } Thank you for any suggestions! Thomas Koch [1] http://hackage.haskell.org/package/dbus-0.10.9

Consider that
interface PasswordStore {
void store(Path path, String secret, Map metadata);
}
is identical to
void store (PasswordStore store, Path path, String secret, Map metadata)
or
store :: PasswordStore -> Path -> secret -> MetaData -> IO ()
So, you can treat PasswordStore as a pure data structure (that has things
like connection details) and just define functions that use it. I wouldn't
worry about grouping the functions together.(*) I'm going to assume you
don't really need an actual interface, but if you did, you could
investigate typeclasses.
Julian.
(*) In general terms, the only reason to group functions together is to
enforce laws that relate the behaviours together e.g. that you can retrieve
something you stored.
On 4 January 2015 at 11:14, Thomas Koch
Hi,
I'm writing a password manager that implements a dbus-api using the dbus[1] package. I'd like to separate the code that implements from the dbus api from the code that stores and retrieves the secrets (passwords). In Java I'd use an interface, e.g.:
interface PasswordStore { void store(Path path, String secret, Map metadata); (String secret, Map metadata) retrieve(Path path); (String secret, Map metadata) search(Map criteria); }
And the dbus-api would export this interface:
dbusClient.export(PasswordStore store)
What would be a Haskell way to do the same? My only idea is to define a record:
data PasswordStore { store :: Path -> Secret -> MetaData -> IO () , retrieve :: Path -> IO (Secret, MetaData) , search :: Criteria -> IO (Secret, MetaData) }
Thank you for any suggestions! Thomas Koch
[1] http://hackage.haskell.org/package/dbus-0.10.9 _______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

On Sun, Jan 4, 2015 at 8:00 PM, Julian Birch
interface PasswordStore { void store(Path path, String secret, Map metadata); }
is identical to
void store (PasswordStore store, Path path, String secret, Map metadata)
or
store :: PasswordStore -> Path -> secret -> MetaData -> IO ()
In fact, Thomas's original PasswordStore definition uses record syntax to simultaneously define 'store' as exactly that. That is, PasswordStore is a data triple and the store function picks out the first one.
So, you can treat PasswordStore as a pure data structure (that has things like connection details) and just define functions that use it. I wouldn't worry about grouping the functions together.(*) I'm going to assume you don't really need an actual interface, but if you did, you could investigate typeclasses.
If I understand correctly he wants the functions together because there's this mysterious piece of Java (?): dbusClient.export(PasswordStore store) I agree that type classes are probably not a good idea here. Thomas, good job on using a record of functions ! But this is the sort of discussion better suited on haskell-cafe, a strict superset of this list, where there are domain experts on dbus to contribute. Haskell-beginners is not better, merely more responsive on language rudiments and libraries circa haskell 98 and LYAH.
Julian.
(*) In general terms, the only reason to group functions together is to enforce laws that relate the behaviours together e.g. that you can retrieve something you stored.
On 4 January 2015 at 11:14, Thomas Koch
wrote: Hi,
I'm writing a password manager that implements a dbus-api using the dbus[1] package. I'd like to separate the code that implements from the dbus api from the code that stores and retrieves the secrets (passwords). In Java I'd use an interface, e.g.:
interface PasswordStore { void store(Path path, String secret, Map metadata); (String secret, Map metadata) retrieve(Path path); (String secret, Map metadata) search(Map criteria); }
And the dbus-api would export this interface:
dbusClient.export(PasswordStore store)
What would be a Haskell way to do the same? My only idea is to define a record:
data PasswordStore { store :: Path -> Secret -> MetaData -> IO () , retrieve :: Path -> IO (Secret, MetaData) , search :: Criteria -> IO (Secret, MetaData) }
Thank you for any suggestions! Thomas Koch
[1] http://hackage.haskell.org/package/dbus-0.10.9 _______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
participants (3)
-
Julian Birch
-
Kim-Ee Yeoh
-
Thomas Koch