Alter option without requiring typeclass

I’m trying to wrap a JS api that takes a record with optional callbacks. I need to apply mkEffect# to each PS callback. Using alter, I can do this but the user needs to add an Alter constraint to their record which is not ideal. For example, say I have an api (x::Int) and I need to make it into (x::String):

g ::
  Alter  (x::Int -> String) (x::Int) (x::String) =>
  Option (x::Int) -> Option (x::String)
g = alter {x: show :: Int -> String }

z ::
  Alter  (x::Int -> String) (x::Int) (x::String) =>
  Option (x::String)
z = f {x: 2}

How can I remove the need for z (the caller) to specify the Alter (x::Int -> String) (x::Int) (x::String) constraint?

Welcome @Rekihyt!
I think you’re actually looking for the modify' function instead of alter. I’m able to take your code snippet and modify it to use modify' and get rid of all the constraints:

g :: Option (x::Int) -> Option (x::String)
g = modify' {x: show :: Int -> String }

z :: Option (x::String)
z = g (fromRecord {x: 2})

The docs for the alter function seem to me like they lie a bit, which is where I think the confusion is coming from. I created an issue to track that here.

2 Likes

You can use alter if you make your input and output Maybe (on the input for whether it was already in the input Option, and on the output for whether it should be in the output Option):

g :: Option (x::Int) -> Option (x::String)
g = alter {x: map show :: Maybe Int -> Maybe String }

z :: Option (x::String)
z = g (fromRecord {x: 2})
1 Like