Open amano-kenji opened 1 year ago
newtype N1 = N1 Int deriving newtype Num
newtype N2 = N2 N1 deriving newtype Num
n2 :: N2
n2 = N2 $ N1 3
hmm = n2 & coercedTo %~ (*2)
Now, does coercedTo
coerce N2
to N1
or Int
?
hmm = n2 & coercedTo %~ (*2)
<interactive>:9:12: error:
• Couldn't match representation of type ‘Integer’
with that of ‘Int’
arising from a use of ‘coercedTo’
• In the first argument of ‘(%~)’, namely ‘coercedTo’
In the second argument of ‘(&)’, namely ‘coercedTo %~ (* 2)’
In the expression: n2 & coercedTo %~ (* 2)
I didn't really think about nested newtypes. But, there is Control.Lens.Wrapped
which I used when I used lens.
That uses ExtendedDefaultRules
enabled in ghci
, (EDIT: Which defaults the type of 2
to be Integer
). In source files the error will be different (and equally or more unhelpful).
I don't think there's any fundamental reason why we couldn't port Control.Lens.Wrapped
, it's just that nobody has felt the need to. Unwrapping a single layer of a newtype is a reasonable request, it just isn't what coerced
provides.
I think it's not worthy copying Wrapped
.
Firstly, it's not just newtype unwrapper, there is
instance Wrapped (Seq a) where
type Unwrapped (Seq a) = [a]
for example.
Secondly, there is https://hackage.haskell.org/package/newtype and https://hackage.haskell.org/package/newtype-generics which kind of do similar thing, but interestingly there is no newtype-coerce
building on top of Coercible
.
I don't think that yet another take should be added to optics
. So far we mostly successfully avoided redoing things (the Ix
/ At
being the only exception can think of, but that has a reason - it's very optics
specific take).
A minimal example of unwrapping a newtype
@Int
bugs me. When I unwrap a newtype, I shouldn't have to specify the wrapped type.coerced
often fails to infer the right types without explicit type declarations.