Update PureScript 0.13 -> 0.14 Type synonyms

Hey everybody!
I have variable record types in order to not repeating myself:

type Identity a
  = a

type Template col maybe r
  = ( bio :: col (maybe Bio)
    , email :: col Email
    , image :: col (maybe Image)
    , password :: col Password
    , username :: col Username
    | r
    )

type Raw
  = { | Template Identity Maybe () }

With the new release PureScript 0.14, I get

    Type synonym Server.User.Type.Misc.Template is partially applied.
    Type synonyms must be applied to all of their type arguments.

I don’t know how the migration guide applies in this case.
Does somebody know how to fix this?

3 Likes

I’m not getting any errors with this

type Identity :: forall k. k -> k
type Identity a = a

type Template :: forall k. (Type -> k) -> (Type -> Type) -> Row k -> Row k
type Template col maybe r
  = ( bio :: col (maybe Int)
    , email :: col Int
    , image :: col (maybe Int)
    , password :: col Int
    , username :: col Int
    | r
    )

type Raw = { | Template Identity Maybe () }

So it’s most likely one of your other types: Bio, Email, etc.

Can you please post a whole module - preferably self contained - which produces the error? The Template type synonym is clearly fully applied in the snippet you’ve included so I am wondering if there’s another place it’s used where it’s only partially applied.

1 Like

ok, thanks. Here is a minimal example

module Misc where

import Data.Maybe (Maybe)

type Template :: forall k. (Type -> k) -> (Type -> Type) -> Row k -> Row k
type Template col maybe r
  = ( bio :: col (maybe String)
    | r
    )

type Identity :: forall k. k -> k
type Identity a
  = a

type Patch
  = { | Template Maybe Identity () }

I get the error message

  Type synonym Misc.Template is partially applied.
  Type synonyms must be applied to all of their type arguments.

only if I use the next code too

module UpdateDto where

import Prelude

import Data.Eq.Generic (genericEq)
import Data.Generic.Rep (class Generic)
import Data.Show.Generic (genericShow)
import Misc (Patch)

newtype UpdateDto
  = UpdateDto { user :: Patch }

derive instance genericUpdateDto :: Generic UpdateDto _

instance showUpdateDto :: Show UpdateDto where
  show = genericShow

instance eqUpdateDto :: Eq UpdateDto where
  eq = genericEq

Shouldn’t this be?

type Template :: forall k. (k -> Type) -> (Type -> Type) -> Row Type -> Row Type

If changed above, does this compile?

type Patch
 = Record (Template Maybe (Identity ()))

Actually, I didn’t come up with the kind signatures. It was the IDE.

type Template :: forall k. (k -> Type) -> (Type -> Type) -> Row Type -> Row Type
type Template col maybe r
  = ( bio :: col (maybe String)
    | r
    )

type Identity :: forall k. k -> k
type Identity a
  = a

type Patch
  = Record (Template Maybe (Identity ()))

gives me at the second maybe

  Could not match kind Type with kind k while checking that type maybe String has kind k
while inferring the kind of col (maybe String)
while inferring the kind of ( bio :: col (maybe String)
                            | r
                            )
in type synonym Template

Let’s try even simpler

module Misc where

type Template col
  = ( bio :: col String
    )

type Identity a
  = a

type Patch
  = { | Template Identity }
Type synonym Misc.Template is partially applied.
Type synonyms must be applied to all of their type arguments.

in the last line. (With module UpdateDto mentioned ealier).
My versions are spago 0.20.3, purs 0.14.1.

Minimal example is:

Misc.purs:

module Misc where
  
type Template col = { bio :: col String }

type Identity a = a

type Patch = Template Identity

+ Other.purs:

module Other where

import Prelude

import Misc 

newtype UpdateDto = UpdateDto Patch

derive instance eqUpdateDto :: Eq UpdateDto
  • It can’t be triggered in one file.
  • It has one of those error positions where it’s caused by the existence of Other.purs, but identified in Misc.purs
  • It can be worked around by inlining the Identity synonym usage (newtype UpdateDto = UpdateDto (Template Identity))
  • Possibly related to https://github.com/purescript/purescript/issues/4101#issuecomment-855259718 given those properties?

type Identity a = a is a bit of a naughty synonym, I think Haskell won’t let you use it this way at all, but because we eagerly and fully expand all synonyms it’s a trick that works as long as it’s only being passed to other synonyms, and doesn’t end up partially applied once everything is expanded out.

I assume either something about synonym expansion had to change for the type system enhancements, or it’s related to the externs handling as per the comment of Nate’s I linked to. Given that it can be fixed by removing the intermediate Patch synonym, it seems like it should be fixable.

4 Likes

ok thanks. I guess I create a bug report then.

2 Likes