我可以表达一个子类约束吗?
Can I express a subclassing constraint?
仍在玩弄约束条件下的存在主义(只是探索这种设计 space,我知道许多 Haskeller 认为它很糟糕)。有关详细信息,请参阅 。
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE ConstraintKinds #-}
{-# Language TypeApplications #-}
import GHC.Exts (Constraint)
class Foo a where
foo :: a -> Int
class Foo a => Bar a where
bar :: a -> String
instance Foo Int where
foo = id
instance Bar Int where
bar = show
data Obj cls = forall o. (cls o) => Obj o
fooable = Obj @Foo $ (42 :: Int)
barable = Obj @Bar $ (42 :: Int)
doFoo :: Obj Foo -> Int
doFoo (Obj x) = foo x
现在我遇到了这个问题。 doFoo fooable
有效,但 doFoo barable
无效。
• Couldn't match type ‘Bar’ with ‘Foo’
Expected type: Obj Foo
Actual type: Obj Bar
• In the first argument of ‘doFoo’, namely ‘barable’
In the expression: doFoo barable
In an equation for ‘it’: it = doFoo barable
这当然是真的。 Obj Foo
与 Obj Bar
不同。
我可以给doFoo
一个合适的类型吗?基本上我想要一个像 Obj cls where cls is a subclass of Foo
这样的类型,但我找不到表达它的方法。请耐心等待,我对这些狂野的奇妙类型是新手。
您可以为此使用量化约束:
{-# LANGUAGE QuantifiedConstraints #-}
doFoo :: forall c . (forall a. c a => Foo a) => Obj c -> Int
doFoo (Obj x) = foo x
本质上,doFoo
接受任何 Obj c
,其中 c
是任何类型 class,这意味着 Foo
,即类型 class满足量化约束
forall a. c a => Foo a
仍在玩弄约束条件下的存在主义(只是探索这种设计 space,我知道许多 Haskeller 认为它很糟糕)。有关详细信息,请参阅
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE ConstraintKinds #-}
{-# Language TypeApplications #-}
import GHC.Exts (Constraint)
class Foo a where
foo :: a -> Int
class Foo a => Bar a where
bar :: a -> String
instance Foo Int where
foo = id
instance Bar Int where
bar = show
data Obj cls = forall o. (cls o) => Obj o
fooable = Obj @Foo $ (42 :: Int)
barable = Obj @Bar $ (42 :: Int)
doFoo :: Obj Foo -> Int
doFoo (Obj x) = foo x
现在我遇到了这个问题。 doFoo fooable
有效,但 doFoo barable
无效。
• Couldn't match type ‘Bar’ with ‘Foo’
Expected type: Obj Foo
Actual type: Obj Bar
• In the first argument of ‘doFoo’, namely ‘barable’
In the expression: doFoo barable
In an equation for ‘it’: it = doFoo barable
这当然是真的。 Obj Foo
与 Obj Bar
不同。
我可以给doFoo
一个合适的类型吗?基本上我想要一个像 Obj cls where cls is a subclass of Foo
这样的类型,但我找不到表达它的方法。请耐心等待,我对这些狂野的奇妙类型是新手。
您可以为此使用量化约束:
{-# LANGUAGE QuantifiedConstraints #-}
doFoo :: forall c . (forall a. c a => Foo a) => Obj c -> Int
doFoo (Obj x) = foo x
本质上,doFoo
接受任何 Obj c
,其中 c
是任何类型 class,这意味着 Foo
,即类型 class满足量化约束
forall a. c a => Foo a