如何应用增量特异性,在 Haskell 中使用子类化?
How to apply incremental specificity, using subclassing in Haskell?
我正在尝试在 Haskell 中使用 subclassing 来对我的 classes 应用增量特异性,但没有成功。
我的第一次尝试:
module Subclassing where
class SuperClass a where
type TheType a :: *
theFunc :: TheType a -> TheType a
class SuperClass b => SubClass b where
type TheType b = Int
data MyType
instance SubClass MyType where
theFunc x = x + x
产生了这个:
Subclassing.hs:10:8: error:
‘TheType’ is not a (visible) associated type of class ‘SubClass’
Subclassing.hs:15:3: error:
‘theFunc’ is not a (visible) method of class ‘SubClass’
我想知道是否有一些语法方法可以将 superclass' types/methods 暴露给 subclass。所以,我在网上搜索了一下,但没有找到任何东西。
在我的第二次尝试中,我试图通过定义 superclass 的通用实例来强制解决这个问题,限制在 subclass:
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
module Subclassing where
class SuperClass a where
type TheType a :: *
theFunc :: TheType a -> TheType a
class SubClass b
instance SubClass c => SuperClass c where
type TheType c = Int
data MyType
instance SubClass MyType
instance SuperClass MyType where
theFunc x = x + x
testFunc :: SuperClass d => [TheType d] -> TheType d
testFunc = sum . (map theFunc)
它产生了这个:
Subclassing2.hs:25:23: error:
• Overlapping instances for SuperClass a0
arising from a use of ‘theFunc’
Matching givens (or their superclasses):
SuperClass d
bound by the type signature for:
testFunc :: SuperClass d => [TheType d] -> TheType d
at Subclassing2.hs:24:1-52
Matching instances:
instance SubClass c => SuperClass c
-- Defined at Subclassing2.hs:15:10
instance SuperClass MyType -- Defined at Subclassing2.hs:21:10
(The choice depends on the instantiation of ‘a0’)
• In the first argument of ‘map’, namely ‘theFunc’
In the second argument of ‘(.)’, namely ‘(map theFunc)’
In the expression: sum . (map theFunc)
在我的第三次尝试中,我尝试将 subclass 设为类型而不是 class。
(我意识到,由于 newtype 值构造函数的单个字段限制,这将具有有限的适用性,但没有想法。):
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
module Subclassing where
class SuperClass a where
type TheType a :: *
theFunc :: TheType a -> TheType a
newtype SubClass = SubClass { unSubClass :: Int -> Int }
instance SuperClass SubClass where
type TheType SubClass = Int
theFunc = unSubClass
testFunc :: SuperClass d => [TheType d] -> TheType d
testFunc = sum . (map theFunc)
它产生了这个:
Subclassing3.hs:17:13: error:
• Couldn't match type ‘Int -> Int’ with ‘Int’
Expected type: TheType SubClass -> TheType SubClass
Actual type: SubClass -> Int -> Int
• In the expression: unSubClass
In an equation for ‘theFunc’: theFunc = unSubClass
In the instance declaration for ‘SuperClass SubClass’
Subclassing3.hs:20:23: error:
• Couldn't match type ‘TheType a0’ with ‘TheType d’
Expected type: TheType a0 -> TheType d
Actual type: TheType a0 -> TheType a0
NB: ‘TheType’ is a type function, and may not be injective
The type variable ‘a0’ is ambiguous
• In the first argument of ‘map’, namely ‘theFunc’
In the second argument of ‘(.)’, namely ‘(map theFunc)’
In the expression: sum . (map theFunc)
• Relevant bindings include
testFunc :: [TheType d] -> TheType d
(bound at Subclassing3.hs:20:1)
你的第一个猜测对我来说似乎足够合理,但不,Haskell 不允许在 (sub)class 定义中定义关联类型或方法。
我正在尝试在 Haskell 中使用 subclassing 来对我的 classes 应用增量特异性,但没有成功。
我的第一次尝试:
module Subclassing where
class SuperClass a where
type TheType a :: *
theFunc :: TheType a -> TheType a
class SuperClass b => SubClass b where
type TheType b = Int
data MyType
instance SubClass MyType where
theFunc x = x + x
产生了这个:
Subclassing.hs:10:8: error:
‘TheType’ is not a (visible) associated type of class ‘SubClass’
Subclassing.hs:15:3: error:
‘theFunc’ is not a (visible) method of class ‘SubClass’
我想知道是否有一些语法方法可以将 superclass' types/methods 暴露给 subclass。所以,我在网上搜索了一下,但没有找到任何东西。
在我的第二次尝试中,我试图通过定义 superclass 的通用实例来强制解决这个问题,限制在 subclass:
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
module Subclassing where
class SuperClass a where
type TheType a :: *
theFunc :: TheType a -> TheType a
class SubClass b
instance SubClass c => SuperClass c where
type TheType c = Int
data MyType
instance SubClass MyType
instance SuperClass MyType where
theFunc x = x + x
testFunc :: SuperClass d => [TheType d] -> TheType d
testFunc = sum . (map theFunc)
它产生了这个:
Subclassing2.hs:25:23: error:
• Overlapping instances for SuperClass a0
arising from a use of ‘theFunc’
Matching givens (or their superclasses):
SuperClass d
bound by the type signature for:
testFunc :: SuperClass d => [TheType d] -> TheType d
at Subclassing2.hs:24:1-52
Matching instances:
instance SubClass c => SuperClass c
-- Defined at Subclassing2.hs:15:10
instance SuperClass MyType -- Defined at Subclassing2.hs:21:10
(The choice depends on the instantiation of ‘a0’)
• In the first argument of ‘map’, namely ‘theFunc’
In the second argument of ‘(.)’, namely ‘(map theFunc)’
In the expression: sum . (map theFunc)
在我的第三次尝试中,我尝试将 subclass 设为类型而不是 class。 (我意识到,由于 newtype 值构造函数的单个字段限制,这将具有有限的适用性,但没有想法。):
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
module Subclassing where
class SuperClass a where
type TheType a :: *
theFunc :: TheType a -> TheType a
newtype SubClass = SubClass { unSubClass :: Int -> Int }
instance SuperClass SubClass where
type TheType SubClass = Int
theFunc = unSubClass
testFunc :: SuperClass d => [TheType d] -> TheType d
testFunc = sum . (map theFunc)
它产生了这个:
Subclassing3.hs:17:13: error:
• Couldn't match type ‘Int -> Int’ with ‘Int’
Expected type: TheType SubClass -> TheType SubClass
Actual type: SubClass -> Int -> Int
• In the expression: unSubClass
In an equation for ‘theFunc’: theFunc = unSubClass
In the instance declaration for ‘SuperClass SubClass’
Subclassing3.hs:20:23: error:
• Couldn't match type ‘TheType a0’ with ‘TheType d’
Expected type: TheType a0 -> TheType d
Actual type: TheType a0 -> TheType a0
NB: ‘TheType’ is a type function, and may not be injective
The type variable ‘a0’ is ambiguous
• In the first argument of ‘map’, namely ‘theFunc’
In the second argument of ‘(.)’, namely ‘(map theFunc)’
In the expression: sum . (map theFunc)
• Relevant bindings include
testFunc :: [TheType d] -> TheType d
(bound at Subclassing3.hs:20:1)
你的第一个猜测对我来说似乎足够合理,但不,Haskell 不允许在 (sub)class 定义中定义关联类型或方法。