仅在 Haskell 平台中就有几个具有许多重叠模块的泛型库(syb
, Data.Typeable
, Data.Data
, GHC.Generics
),但是我在执行非常基本的泛型编程任务时遇到了麻烦。
我希望能够在相同形状的类型之间进行转换,即我希望在同构类型之间实现多态、类型化的转换函数,本质上是本文末尾提供的(PDF),其中提到了索引类型族。
我不关心废弃我的样板,而是能够围绕 sum 和 product 抽象构建新的库。
下面的问题是GHC.Generic
我认为最接近我需要的问题,但欢迎使用其他解决方案。
以下两种形状相同
data Pair = Pair Char Int deriving (Generic, Show)
data Pair2 = Pair2 Char Int deriving (Generic, Show)
我想使用 GHC.Generics 在它们之间转换值。由于所有幻像参数和其他废话,以下内容无法进行类型检查:
f :: Pair -> Pair2
f = to . from
最终,我想要一个类似的函数,它对任何(或任何其他类可以支持这个)实例fromInteger
都有一个多态返回值。Generic
我想我正在寻找类似的东西GHC.Generics
:
--class:
type family NormalForm a
class ToGeneric a where
to :: a -> NormalForm a
class FromGeneric b where
from :: NormalForm b -> b
--examples:
data A = A Char Int deriving Show
data B = B Char Int deriving Show
type instance NormalForm A = (Char,Int)
instance ToGeneric A where
to (A a b) = (a,b)
instance FromGeneric A where
from (a,b) = A a b
type instance NormalForm B = (Char,Int)
instance ToGeneric B where
to (B a b) = (a,b)
instance FromGeneric B where
from (a,b) = B a b
-- the function I'm looking for
coerce :: (ToGeneric a, FromGeneric b, NormalForm a ~ NormalForm b)=> a -> b
coerce = from . to
有了上面我们可以做我想做的一切:
*Main> (coerce $A 'a' 1) :: B
B 'a' 1
*Main> (coerce $A 'a' 1) :: A
A 'a' 1
编辑:实际上,这就是 Nathan Howell 的f
功能在下面的工作方式。
问题
这可能与目前在 haskell 平台上的库有关吗?
如果没有,是否可以定义一个库来利用现有
deriving
机制Generic
,Data
而不诉诸 TH?