Search code examples
recordspurescriptlenses

How to fix this Purescript error: Could not match {...} with (...)?


I have a state for a halogen component including a lens like this:

import Optic.Core (Lens', lens)

type State =
  { userName :: String
  , password :: String
  , formError :: String
  }

_userName :: Lens' State String
_userName = lens _.userName (\r str -> r { userName = str })

And I want to modify the state in the eval function of the same component like this:

eval :: forall eff.
        Query ~> ParentDSL State Query UserNameField.Query Slot Void (Aff (console :: CONSOLE , ajax :: AJAX | eff))
eval = case _ of
    HandleInput userName next -> do
      -- this code causes trouble:
      _userName .= userName
      -- while this code works:
      -- modify (set _userName userName)
      pure next

However, I get the error message:

  Could not match type

    { userName :: String
    , password :: String
    , formError :: String
    }

  with type

    ( userName :: String
    , password :: String
    , formError :: String
    )


while trying to match type t3
                             { userName :: String
                             , password :: String
                             , formError :: String
                             }
  with type t2
while checking that expression _userName
  has type (t0 -> t1) -> t2 -> t2
in value declaration eval

where t1 is an unknown type
      t0 is an unknown type
      t2 is an unknown type
      t3 is an unknown type
 [TypesDoNotUnify]

Note the difference between { and ( (took me a while). I don't even know what the latter type actually means and I have no clue why this error is introduced by a MonadState-based lense.


Solution

  • Mystery solved: I unintentionally mixed two packages

    purescript-lens and purescript-profunctor-lenses. My lenses came from the former and the assign function (.=) is only present in the latter, which was installed apparently as some implicit subdependency.