gat*_*ado 7 haskell typeclass deriving
假设我有类似的数据类型
data D a = D a a a
Run Code Online (Sandbox Code Playgroud)
和一个类型类
class C c ...
instance (C c1, C c2) => C (c1, c2)
Run Code Online (Sandbox Code Playgroud)
然后,我希望能够写作
data D a = D a a a deriving C
Run Code Online (Sandbox Code Playgroud)
并生成一个实例,
instance C ((a, a), a) => C (D a)
Run Code Online (Sandbox Code Playgroud)
通过使用模惰性评估同构,
D a ~ ((a, a), a)
Run Code Online (Sandbox Code Playgroud)
注意.使用newtype,GeneralizedNewtypeDeriving
如果有一个,则无法使用data D m = D (m Integer) (m Integer)
.
注2.这个问题一般与Haskell表达有关 - 像Python这样的语言有一个名为元组的东西,它可以在任何使用元组的地方使用; 这个问题显示我在哪里/如何不知道如何在Haskell中模拟相同的事情.
rei*_*erp 14
使用GHC 7.4的通用编程支持,您可以相对干净,高效地完成此任务.GHC.Generics的文档可能会有所帮助.这是一个例子.
考虑以下示例类和一些示例实例:
class C a where
-- | Double all numbers
double :: a -> a
instance C Int where
double i = 2 * i
instance (C a, C b) => C (a, b) where
double (a, b) = (double a, double b)
Run Code Online (Sandbox Code Playgroud)
我们需要一些语言编译指示和导入:
{-# LANGUAGE TypeOperators, DefaultSignatures, DeriveGeneric, FlexibleContexts, FlexibleInstances #-}
module Example where
import GHC.Generics hiding(C, D)
Run Code Online (Sandbox Code Playgroud)
我们现在给出一些"通用实例".泛型类型都有一个幻像参数x
,这使得实例头更复杂一些:
-- "Insert" a normal value into a generic value
instance C c => C (K1 i c x) where
double (K1 c) = K1 (double c)
-- Ignore meta-information (constructor names, type names, field names)
instance C (f x) => C (M1 i c f x) where
double (M1 f) = M1 (double f)
-- Tuple-like instance
instance (C (f x), C (g x)) => C ((f :*: g) x) where
double (f :*: g) = double f :*: double g
Run Code Online (Sandbox Code Playgroud)
我们现在重新定义我们的课程C
以利用GC
class C a where
-- | Double all numbers
double :: a -> a
-- specify the default implementation for double
default double :: (Generic a, C (Rep a ())) => a -> a
double = to0 . double . from0
-- from, with a more specialised type, to avoid ambiguity
from0 :: Generic a => a -> Rep a ()
from0 = from
-- to, with a more specialised type, to avoid ambiguity
to0 :: Generic a => Rep a () -> a
to0 = to
Run Code Online (Sandbox Code Playgroud)
现在我们可以非常轻松地定义一些实例:
data D a = D a a a deriving Generic
instance C a => C (D a)
data D2 m = D2 (m Int) (m Int) deriving Generic
instance C (D2 D)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1137 次 |
最近记录: |