λ x + y = getSum $ Sum x `mappend` Sum y
λ 1 + 2
3
我想象一组函数,比如
withSum
、withSum2
等等,可以自动为每个newtype
滚动出来。或者可能创建一个参数化的Identity
,供ApplicativeDo
使用。或者可能还有其他我没想到的方法。我想知道这方面是否有先前的艺术或理论。
附言:我对
coerce
不满意,原因有两个。
safety I thought it is not very safe. After being pointed that it is actually safe, I tried a few things and I could not do anything harmful, because it requires a type annotation when there is a possibility of ambiguity. For example:
λ newtype F = F Int deriving Show λ newtype G = G Int deriving Show λ coerce . (mappend (1 :: Sum Int)) . coerce $ F 1 :: G G 2 λ coerce . (mappend (1 :: Product Int)) . coerce $ F 1 :: G G 1 λ coerce . (mappend 1) . coerce $ F 1 :: G ... • Couldn't match representation of type ‘a0’ with that of ‘Int’ arising from a use of ‘coerce’ ...
But I would still not welcome
coerce
, because it is far too easy to strip a safety label and shoot someone, once the reaching for it becomes habitual. Imagine that, in a cryptographic application, there are two values:x :: Prime Int
andx' :: Sum Int
. I would much rather typegetPrime
andgetSum
every time I use them, thancoerce
everything and have one day made a catastrophic mistake.usefulness
coerce
does not bring much to the table regarding a shorthand for certain operations. The leading example of my post, that I repeat here:λ getSum $ Sum 1 `mappend` Sum 2 3
— Turns into something along the lines of this spiked monster:
λ coerce $ mappend @(Sum Integer) (coerce 1) (coerce 2) :: Integer 3
— Which is hardly of any benfit.
coerce
作为缩写的批评,请看我的回答。你不是强制输入和输出(这确实比应用 newtype 构造器/获取器好一点,但并没有多少优势)而是强制转换你想要调用的函数,使其具有不同的类型。至于安全性,它与手动展开一样安全或不安全。如果你想让这变得不可能,请勿导出 newtype 构造器,那么coerce
也不起作用。如果你能搞清楚coerce
,你也能搞清楚手动 newtype 展开。 - Ben