【发布时间】:2019-04-22 22:41:45
【问题描述】:
为了水平集,这里有一个简单的函子:
data Box a = Box a deriving (Show)
instance Functor Box where
fmap f (Box x) = Box (f x)
这让我们可以“在盒子里”操作:
> fmap succ (Box 1)
Box 2
如何使用新类型实现同样的语法便利?假设我有以下内容:
newtype Width = Width { unWidth :: Int } deriving (Show)
newtype Height = Height { unHeight :: Int } deriving (Show)
这有点笨拙:
> Width $ succ $ unWidth (Width 100)
Width {unWidth = 101}
这样就好了:
> fmap succ (Width 100) -- impossible?
Width {unWidth = 101}
当然,我不能将 Width 或 Height 作为 Functor 的实例,因为两者都没有类型 * -> *。虽然在语法上他们感觉与 Box 没有什么不同,因此看起来应该可以在没有所有手动包装和展开的情况下对底层值进行操作。
另外,创建 n 个这样的函数并不令人满意,因为每个新类型都会重复:
fmapWidth :: (Int -> Int) -> Width -> Width
fmapHeight :: (Int -> Int) -> Height -> Height
如何将 Ints 上的函数提升为 Widths 上的函数?
【问题讨论】:
标签: haskell