Giter Site home page Giter Site logo

Comments (2)

the-dr-lazy avatar the-dr-lazy commented on August 15, 2024

With the proposed design, there is no way to have multiple Validatable a instances for type a with different raw inputs.
So, this is my new suggestion:

newtype Username = Username { un :: Text }

instance Validatable A Username where
  type Parsed Username = Username
  type Errors Username = AValidationErrors
  
  validate :: A -> Sem '[] (Validation ValidationErrors Username)
  validate = undefined

instance Validatable B Username where
  type Parsed Username = Username
  type Errors Username = BValidationErrors
  
  validate :: B -> Sem '[] (Validation ValidationErrors Username)
  validate = undefined

And for Form v:

data Form (v :: Validity) = Form
  { usernameA :: Validate v A Username
  , usernameB :: Validate v B Username
  }
  deriving stock Generic

-- Because the Validatable is a multi-param typeclass we should use standalone deriving
deriving via (Generically (Form v)) instance Validatable (Form 'Raw) (From 'Parsed)

from cascade.

the-dr-lazy avatar the-dr-lazy commented on August 15, 2024

There was an issue with safe coercion through Sem r a type from polysemy.

https://github.com/polysemy-research/polysemy/blob/c37d485b614e98622f5e7473a478b781a6ad5c45/src/Polysemy/Internal.hs-boot#L7

Both type variables of Sem r a are nominal which causes Sem r (Generically a) not to be coercible with Sem r a.
So here is the deal!

I made a type family called Parsed which deconstruct Generically type:

type family Parsed (a :: Type) :: Type where
  Parsed (Generically a) = a
  Parsed a               = a

Then the Validatable.validate function type signature would become:

validate :: raw -> Sem (Effects raw parsed) (Validation (Errors raw parsed) (Parsed parsed))

By now we are able to derive Validatable typeclass via Generically but due to usage of Parsed parsed in the return type of validate compiler needs disambiguation.

f :: Form 'Raw -> Sem '[] (Validation (Errors (Form 'Raw) (From 'Parsed)) (Form 'Parsed))
f = validate -- Ambiguous parsed0

To solve ambiguity, I renamed the Validatable.validate function to Validatable.parse and introduced another function with the following constraints:

validate :: forall raw parsed
          . Validatable raw parsed
         => parsed ~ Parsed parsed
         => raw
         -> Sem
              (Effects raw parsed)
              (Validation (Errors raw parsed) parsed)
validate = parse @raw @parsed

from cascade.

Related Issues (13)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.