Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    vlj
    @vlj
    so I'm deconstructing my type in all function and rebuilding it all the time

    For instance here is one function I use to update and object :

    changeTask :: EndEvent -> MeasuredTask  -> Maybe MeasuredTask
    changeTask s (MeasuredTask task) =
      Just $ MeasuredTask $ (set _timeEnd s.time) <<< (set _cpuEnd s.cpuTicks) <<< (over _cpuThread ((+) s.cpuTicks)) $ task

    I need to destructure in the arg, apply the lenses, and at the end call the constructor back

    is there a more elegant way to do ?
    unclechu
    @unclechu:matrix.org
    [m]
    the lenses act on records, and records in PureScript are just { ... } whilst MeasuredTask is just wrapping that record. you need to map it
    actually PureScript has nice syntax to operate on records, so you might not need all these lenses
    vlj
    @vlj
    which syntax ?
    unclechu
    @unclechu:matrix.org
    [m]
    { timeEnd = _ } gives you a function, if i remember the syntax correctly
    @vlj: PureScript syntax. i’d recommend you to read this document i wrote in 2018:
    https://github.com/unclechu/purescript-for-haskellers
    vlj
    @vlj

    btw doing

    
    changeTask :: EndEvent -> MeasuredTask  -> Maybe MeasuredTask
    changeTask s task =
      Just $ (set _timeEnd s.time) <<< (set _cpuEnd s.cpuTicks) <<< (over _cpuThread ((+) s.cpuTicks)) <$> task

    didn't work (error msg is :

    
      Could not match type
    
        MeasuredTask
    
      with type
    
        t0
          { cpuEnd :: Int    
          , cpuThread :: Int 
          , timeEnd :: String
          | t1
          }
    
    
    while checking that type MeasuredTask
      is at least as general as type t0
                                       { cpuEnd :: Int    
                                       , cpuThread :: Int 
                                       , timeEnd :: String
                                       | t1
                                       }
    while checking that expression task
      has type t0
                 { cpuEnd :: Int    
                 , cpuThread :: Int 
                 , timeEnd :: String
                 | t1
                 }
    in value declaration changeTask
    
    where t0 is an unknown type
          t1 is an unknown type
    ok thank I'm reading it
    unclechu
    @unclechu:matrix.org
    [m]
    for instance _ { foo { bar { baz = 42 } } }, you don’t need lenses to do this

    i think this is equivalent to your code:

    changeTask :: EndEvent -> MeasuredTask  -> Maybe MeasuredTask
    changeTask s task =
      Just $ (\x -> x { timeEnd = s.time, cpuEnd = s.cpuTicks, cpuThread = x.cpuThread + s.cpuTicks }) <$> task

    did not test this though. also there might be a syntax for over-like modification but i don’t remember it. maybe there’s no such syntax

    vlj
    @vlj
    ok thanks for the hint about this syntax !
    it doesn't work :/ it wants task to be a record and not a MeasuredTask
    unclechu
    @unclechu:matrix.org
    [m]
    @vlj: i fixed the last example a bit
    @vlj: could you show the code and the error?
    vlj
    @vlj
    at src\ParseEvents.purs:116:104 - 116:108 (line 116, column 104 - line 116, column 108)
    
      Could not match type
    
        MeasuredTask
    
      with type
    
        t0
          { cpuEnd :: t1    
          , cpuThread :: Int
          , timeEnd :: t2   
          | t3
          }
    
    
    while checking that type MeasuredTask
      is at least as general as type t0
                                       { cpuEnd :: t1    
                                       , cpuThread :: Int
                                       , timeEnd :: t2   
                                       | t3
                                       }
    while checking that expression task
      has type t0
                 { cpuEnd :: t1    
                 , cpuThread :: Int
                 , timeEnd :: t2   
                 | t3
                 }
    in value declaration changeTask
    
    where t0 is an unknown type
          t3 is an unknown type
          t2 is an unknown type
          t1 is an unknown type
    here is a pastebin by the way : https://pastebin.com/VMRiXSKF
    in the pastebin it's line 116
    unclechu
    @unclechu:matrix.org
    [m]
    @vlj: i don’t see Functor MeasuredTask instance there
    vlj
    @vlj
    ho yes right
    unclechu
    @unclechu:matrix.org
    [m]
    i think flipped map would fit this better:
    changeTask :: EndEvent -> MeasuredTask  -> Maybe MeasuredTask
    changeTask s task =
      Just $ task <#> \x -> x { timeEnd = s.time, cpuEnd = s.cpuTicks, cpuThread = x.cpuThread + s.cpuTicks }
    vlj
    @vlj
    what does flipped map do ?
    unclechu
    @unclechu:matrix.org
    [m]
    @vlj: the same as regular map but the arguments are flipped
    @vlj: like <&> in haskell
    vlj
    @vlj
    ok
    vlj
    @vlj
    how do I define a functor instance over MeasuredTask by the way ? MeasuredTask is a specific type
    
    instance functor :: Functor MeasuredTask where
      map f (MeasuredTask mt) = MeasuredTask (f mt)
    complains that
    
      Could not match kind
    
        Type -> Type
    
      with kind
    
        Type
    
    
    while checking the kind of Functor MeasuredTask
    seems like there is a conflict with typename and constructor
    actually no it's the same
    unclechu
    @unclechu:matrix.org
    [m]
    @vlj: i think you can derive it: derive instance functorMeasuredTask :: Functor MeasuredTask
    @vlj: btw, you can replace data with newtype for MeasuredTask since it wraps only one single value
    ah, i’m wrong about the functor
    @vlj: you should either use something like Functor1 or destructure MeasuredTask
    damn, i don’t think any functor would work here 😅
    MeasuredMask don’t have any type argument to map
    vlj
    @vlj
    yes
    unclechu
    @unclechu:matrix.org
    [m]
    changeTask :: EndEvent -> MeasuredTask -> Maybe MeasuredTask
    changeTask s (MeasuredTask task) =
      Just $ MeasuredTask $ task { timeEnd = s.time, cpuEnd = s.cpuTicks, cpuThread = task.cpuThread + s.cpuTicks }
    vlj
    @vlj
    thanks
    unclechu
    @unclechu:matrix.org
    [m]
    @vlj: by the way, look at this module, it may really help to do functor-like stuff for newtypes with kind of just Type https://pursuit.purescript.org/packages/purescript-newtype/3.0.0/docs/Data.Newtype#t:Newtype
    for instance:
    newtype Label = Label String
    derive instance newtypeLabel :: Newtype Label _
    
    toUpperLabel :: Label -> Label
    toUpperLabel = over Label String.toUpper
    vlj
    @vlj
    ok
    btw it's not possible to make tuple like in Haskell ? For instance type XYZ = (Int, String)
    unclechu
    @unclechu:matrix.org
    [m]
    @vlj: I think there is no special syntax for tuples in PureScript. in Haskell there is just a bunch of syntactic sugar for regular data-types: https://hackage.haskell.org/package/ghc-prim-0.6.1/docs/GHC-Tuple.html#t:-40--44--44--44--44--44--44--41-
    vlj
    @vlj
    ok
    unclechu
    @unclechu:matrix.org
    [m]
    you can define them by yourself if you really need it
    vlj
    @vlj

    I'm trying to build a state monad but I get a RangeError due to maximum call stack size exceeded, my code is :

    
    type ProcessEventContext = Tuple (Map Int MeasuredTask) (Int)
    
    processStartEvent :: StartEvent -> State (ProcessEventContext) (Map Int MeasuredTask)
    processStartEvent s = do
      state <- get
      let map = fst state
      let stack = snd state
      pure $ map
    
    processStopEvent :: EndEvent -> State (ProcessEventContext) (Map Int MeasuredTask)
    processStopEvent s = do
      state <- get
      let map = fst state
      let stack = snd state
      pure $ map
    
    processTickEvent :: TickEvent -> State (ProcessEventContext) (Map Int MeasuredTask)
    processTickEvent s = do
      state <- get
      let map = fst state
      let stack = snd state
      pure $ map
    
    processDoNothing :: State (ProcessEventContext) (Map Int MeasuredTask)
    processDoNothing = do
      state <- get
      let map = fst state
      let stack = snd state
      pure $ map
    
    
    updateMap old (Start s) = processStartEvent s
    updateMap old (Stop s) = processStopEvent s
    updateMap old (Tick s) = processTickEvent s
    updateMap old (_) = processDoNothing
    
    eventToTaskM :: Array Event -> State (ProcessEventContext) (Map Int MeasuredTask)
    eventToTaskM list = do
        _ <- foldM updateMap empty list
        result <- get
        pure $ fst result
    
    
    eventToTask :: Array Event -> Map Int MeasuredTask
    eventToTask list =
      fst $ runState (eventToTaskM list) (Tuple empty 0)

    Is there a way to circumvent the issue ? I suspect it's due to foldM (the list has 100000s events)

    vlj
    @vlj

    actually I'm struggling with something else entirely, the state monad doesn't do what I'm expecting it do to. Here is the code :

    type ProcessEventContext = Tuple (Map Int MeasuredTask) (Int)
    
    processStartEvent :: StartEvent -> State (ProcessEventContext) Unit
    processStartEvent s = do
      old <- gets fst
      stack <- gets snd
      let updatedMap = (insert (s.iD) (createStartInfo s) old)
      put $ Tuple updatedMap stack
    
    processStopEvent :: EndEvent -> State (ProcessEventContext) Unit
    processStopEvent s = do
      state <- get
      let old = fst state
      let stack = snd state
      let updatedMap = update (changeTask s) s.taskStartId old
      put $ Tuple updatedMap stack
    
    
    processDoNothing :: State (ProcessEventContext) Unit
    processDoNothing = do
      pure unit
    
    updateMap (Start s) = processStartEvent s
    updateMap (Stop s) = processStopEvent s
    updateMap (Tick s) = processDoNothing
    updateMap (_) = processDoNothing
    
    eventToTaskM :: Array Event -> State (ProcessEventContext) (Map Int MeasuredTask)
    eventToTaskM arr = do
        let filtered = \x -> case x of Tick _ -> false
                                       _ -> true
        let filteredEvents = (take 1000 $ filter filtered arr :: Array Event)
        _ <- sequence_ $ updateMap <$> filteredEvents
        result <- get
        pure $ fst result
    
    
    eventToTask :: Array Event -> Map Int MeasuredTask
    eventToTask list =
      evalState (eventToTaskM list) (Tuple empty 0)

    But I always end up with a single item in the map. It looks like the squence is discarding the state