我对如何使用newtype包非常困惑。它的文档似乎暗示非常强大,但我无法弄清楚如何使用提供的函数(而不是接口)来创建我需要的一些函数。例如,我想要一个带签名的函数:
(Newtype n o) => (o -> o -> o) -> n -> n -> n
(Newtype n o, Functor f) => (o -> f o) -> n -> f n
(Newtype n o, Functor f) => (f o -> o) -> f n -> n
使用fmap
,pack
和unpack
的组合来编写这些内容是可行的,但我希望通过神秘的ala
或{{1}可能更清晰函数(或将函数“提升”到新类型而不是从newtype中“解除”它们的轻微变化)。如果重要的是,我特别感兴趣的仿函数是ala'
和Maybe
。
答案 0 :(得分:1)
基于上面的评论,似乎可能没有干净的方法来使用Control.Newtype
提供的hofs编写我需要的函数。但是,似乎还有另一种选择:为非 -newtypes创建实例。
newtype包的示例:
{-# LANGUAGE MultiParamTypeClasses, UndecidableInstances,
FlexibleInstances #-}
import Control.Newtype
instance (Newtype n o) => Newtype [n] [o] where
pack = map pack
unpack = map unpack
instance (Newtype n o) => Newtype (Maybe n) (Maybe o) where
pack = fmap pack
unpack = fmap unpack
instance (Newtype n o, Newtype n' o') => Newtype (n -> n') (o -> o') where
pack f = pack . f . unpack
unpack f = unpack . f . pack
-- a newtype wrapper for Nums
newtype NNum a = NNum {unNNum :: a}
instance Newtype (NNum a) a where
pack = NNum
unpack = unNNum
ntimes5 :: (Num a) => NNum a -> NNum a
ntimes5 = pack sum . replicate 5
foo :: a -> Maybe [a]
foo = undefined
bar :: NNum a -> Maybe [NNum a]
bar = pack foo
正如bheklilr所提到的,这需要UndecidableInstances
,但似乎并不需要过多的签名。但是,我们可以使用newtype-generics包做得更好:
{-# LANGUAGE TypeFamilies, DeriveGeneric #-}
import Control.Newtype
import GHC.Generics
instance (Newtype a) => Newtype [a] where
type O [a] = [O a]
pack = map pack
unpack = map unpack
instance (Newtype a) => Newtype (Maybe a) where
type O (Maybe a) = Maybe (O a)
pack = fmap pack
unpack = fmap unpack
instance (Newtype a, Newtype b) => Newtype (a -> b) where
type O (a -> b) = (O a -> O b)
pack f = pack . f . unpack
unpack f = unpack . f . pack
newtype NNum a = NNum {unNNum :: a} deriving (Generic)
instance Newtype (NNum a)
ntimes5 :: (Num a) => NNum a -> NNum a
ntimes5 = pack sum . replicate 5
foo :: a -> Maybe [a]
foo = undefined
bar :: NNum a -> Maybe [NNum a]
bar = pack foo
(当然,您也可以在此处手动派生Newtype
实例,保存扩展和一次导入。)因此UndecidableInstances
或FlexibleInstances
可能会出现任何问题现在没有实际意义。类型系列与fundeps的比较汇总为here和here。这个例子似乎是类型族提供明确胜利的情况。