Skip to content

strong-path types are restricted to type parameters with kind * #47

@craigmc08

Description

@craigmc08

Currently, the types in this package do not have kind polymorphism, meaning you can only have Dir a if a :: *. But sometimes it would be convenient to allow a to have a different kind.

For example, imagine I want to define a function readREADME :: Project -> IO String which gets the README file from a couple of explicitly defined projects:

data Project = WaspcProject | WasplsProject

To do this with strong-path, I would like to be able to write:

{-# LANGUAGE DataKinds #-}
{-# LANGUAGE PolyKinds #-}

data Project = WaspcProject | WasplsProject

readREADME :: Project -> IO String
readREADME project =
  let readmeFile = case
        WaspcProject -> waspcProjectDir </> readmeFileInProjectDir
        WasplsProject -> wasplsProjectDir </> readmeFileInProjectDir
  in readFile $ toFilePath readmeFile

data READMEFile

readmeFileInProjectDir :: forall (base :: Project). Path' (Rel base) (File READMEFile)
readmeFileInProjectDir = [relfile|README.md|]

waspcProjectDir :: Path' Abs (Dir 'WaspcProject)
waspcProjectDir = [absdir|~/waspc|]

wasplsProjectDir :: Path' Abs (Dir 'WasplsProject)
wasplsProjectDir = [absdir|~/waspls|]

Currently, I have define some extra types WaspcDir and WasplsDir, and then I have to make sure to keep those types in-sync with Project in case I add more constructors. I would also have to make a typeclass to act similar to the Project kind that I could use to limit what readmeFileInProjectDir can be joined with. The goal is to reduce that little bit of boilerplate and work required to keep the constructors and types in-sync.

I think this should be possible to do by enabling -XPolyKinds in this package.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions