[Haskell-cafe] Representing record subtypes, sort of.
Evan Laforge
qdunkan at gmail.com
Tue Nov 11 05:46:26 UTC 2014
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 <kannan at cakoose.com> wrote:
> 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 at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
More information about the Haskell-Cafe
mailing list