[Haskell-cafe] Representing record subtypes, sort of.
Kannan Goundan
kannan at cakoose.com
Tue Nov 11 01:44:05 UTC 2014
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!
More information about the Haskell-Cafe
mailing list