
I would probably write
data Common = Common { ... }
data File = File { fileCommon :: Common, ... }
data Folder = Folder { folderCommon :: Common, ... }
data Entry = EntryFile File | EntryFolder Folder
entry f g (EntryFile a) = f a
entry f g (EntryFolder b) = g b
common = entry fileCommon folderCommon
This is essentially your second approach, but with less scaffolding.
You can pass a Folder to a function wanting an Entry just by composing
EntryFile on the front.
The GADT approach would work too, I suppose, maybe even nicer than mine.
On Mon, Nov 10, 2014 at 5:44 PM, Kannan Goundan
I have an API that, in a language with subtyping, would look like:
class FsEntry id: String
class FsFile extends FsEntry modified: Date size: Int
class FsFolder extends FsEntry owner: String
listFolder :: Path -> [FsEntry] createFile :: Path -> FsFile createFolder :: Path -> FsFolder
(I'm assuming some way of specifying that FsEntry will only ever have those two subtypes.)
How would you represent this in Haskell? My first thought was:
newtype FsEntry = FsEntry FsCommon FsExtra data FsCommon = FsCommon { id: String } data FsExtra = FsFile { modified: Date, size: Int } | FsFolder { owner: String }
But then I couldn't have precise return types for `writeFile` and `createFolder`. My next attempt was to use a type-parameterized top-level class:
data FsCommon = FsCommon { id: String } data FsFileExtra = FsFileExtra { modified: Data, size: Int } data FsFolderExtra = FsFolderExtra { owner: String } data FsEither = FsFile FsFileExta | FsFolder FsFolderExtra
newtype FsEntryBase extra = FsEntryBase FsCommon extra type FsEntry = FsEntryBase FsEither type FsFile = FsEntryBase FsFileExtra type FsFolder = FsEntryBase FsFolderExtra
1. This seems complicated. 2. I can't pass an `FsFolder` to a function expecting an `FsEntry`, but maybe that's just the nature of having subtyping and I have to give up on that (which I'm ok with).
Any suggestions on how to do this? Thanks!
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe