How to write a simple setter function for records?

#1

I tried something like this

let bla :: State -> Array Item -> State
    bla rec val = rec {list: val}

But this doesn’t work because it can’t match the type of “rec {list: val}” with type State.

I’m trying to reduce a lot of if/else condition nesting and duplicate code by making these setters functions. So that i don’t have to hardcore the key that is going to be updated.

#2

rec { list = val }. See https://github.com/purescript/documentation/blob/master/language/Records.md#record-update

#3

@hdgarrood i’m looking for a function as a value that can be passed around. I believe your code is an expression only.

#4

The distinction you’re describing doesn’t really exist; in PureScript, functions are values that can be passed around just like any other. If you can describe in a bit more detail what you’d like to be able to write, I might be able to help more.

#5

Hi @hdgarrood i reduced my code to this mini test case. Like this it type checks.

module Main where

import Prelude

import Data.Const (Const)
import Effect (Effect)
import Effect.Aff (Aff)
import Effect.Class (class MonadEffect)
import Effect.Console (log)
import Halogen as H
import Halogen.Aff as HA
import Halogen.HTML as HH
import Halogen.VDom.Driver (runUI)

type Item = String
type T_A = Array Item
type T_B = Array Item

type State =
  { b :: T_B
  , a :: T_A
  }

initS :: Unit -> State
initS input =
  { b: []
  , a: []
  }

data Bla = A | B

data Action = Drop

main :: Effect Unit
main = do
  log "🍝"
  HA.runHalogenAff do
    body <- HA.awaitBody
    runUI component unit body

component :: H.Component HH.HTML (Const Unit) Unit Void Aff
component =
  H.mkComponent
    { initialState: initS
    , render: \s -> HH.text "add"
    , eval: H.mkEval $ H.defaultEval { handleAction = handleAction }
    }

handleAction ∷ forall o m. MonadEffect m => Action → H.HalogenM State Action () o m Unit
handleAction = case _ of
  Drop -> do
    -- let ds2writer ds = case ds of
    --                      A -> \rec val -> rec {a: val}
    --                      B -> \rec val -> rec {b: val}
    pure unit

When uncommenting the three lines at the end the following happens:

  Could not match type
             
    ( b :: t1
    ...      
    )        
             
  with type
             
    ( a :: t2
    ...      
    )        
             

while trying to match type            
                             ( b :: t1
                             ...      
                             )        
                                      
  with type            
              ( a :: t2
              ...      
              )        
                       
while checking that expression \rec ->         
                                 \val ->       
                                   rec { b: ...
                                       }       
  has type t0
in value declaration handleAction

where t0 is an unknown type
      t2 is an unknown type
      t1 is an unknown type

I’m trying to make a getter for State depending on a condition.

I want to put this right hand side expression \rec val -> rec {a: val} or \rec val -> rec {b: val} into left hand side lvalue

#6

Ok, have you tried replacing the colons with equals signs, eg rec { a = val }?

#7

wow thanks a lot @hdgarrood . I don’t know what i was doing … silly me

1 Like
#8

Welcome! Yeah so just to clarify in case this isn’t already clear, f { a: 1 } means “apply the function f to the record { a: 1 }”, and f { a = 1 } means “update the record f by setting a to 1.”

1 Like