kindaro
October 21, 2020, 1:24pm
#1
Consider a simple example:
> data V2 a = V2 { x :: a, y :: a }
> v2 = V2 { x: V2 { x: 1, y: 2 }, y: V2 { x: 3, y: 4 } }
Suppose I want to extract the 1
. What I tried:
> (x <<< x) v2
Error found: Unknown value x
> v2.x.x
Error found: Could not match type Record with type V2
It seems that I need to unwrap the V2
data constructor. A pattern matching lambda can do that, but I am looking for a more concise solution. There should be a simple way to do this, no?
1 Like
You might want to change your V2
definition to use a type alias. Your current definition is doing unnecessary boxing:
type V2 a = { x :: a, y :: a }
v2 = { x: { x: 1, y: 2}, y: {x: 3, y: 4}}
v2.x.x
If you want more type safety, you should wrap it in a newtype:
newtype V2 a = { x :: a, y :: a }
derive instance newtypeV2 :: Newtype (V2 a) _
v2 = V2 { x: V2 { x: 1, y: 2}, y: V2 {x: 3, y: 4}}
(_.x <<< un V2 <<< _.x <<< un V2) v2
un
is from import Data.Newtype (un)
1 Like
I think you may want to use a newtype
there instead of data
. Then you can do this:
newtype V2 a = V2 { x :: a, y :: a }
derive instance newtypeV2 :: Newtype (V2 a) _
foo = (unwrap $ V2 { x: 1, y: 2}).x
Where Newtype
is from Data.Newtype
.
Edit: derive the instance like @JordanMartinez did.
1 Like
@JordanMartinez You beat me to it!
1 Like
Also, your code doesn’t compile. The newtype
declaration doesn’t have a constructor and it should be Newtype (V2 a) _
.
1 Like
Whoops! Thanks for the correction. I’ve updated my code above.
2 Likes
jy14898
October 23, 2020, 9:51am
#7
I don’t recommend using this, but for fun a wrote a class which unwraps nested newtypes of records like yours
Note that it doesn’t unwrap any/all newtypes in the data, just the ones that are the same type constructor as the top level newtype
1 Like