Can I express a subclassing constraint?

帅比萌擦擦* 提交于 2021-01-27 05:09:16

问题


Still playing with existentials over constraints (just exploring this design space, I know it is considered bad by many Haskellers). See this question for more info.

{-# 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

Now I have this problem. doFoo fooable works, but doFoo barable doesn't.

• 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

Which is of course true. Obj Foo is different for Obj Bar.

Can I give a suitable type to doFoo? Basically I want a type like Obj cls where cls is a subclass of Foo but I cannot find a way to express it. Please bear with me, I'm new to these wild wonderful types.


回答1:


You can use a quantified constraint for that:

{-# LANGUAGE QuantifiedConstraints #-}

doFoo :: forall c . (forall a. c a => Foo a) => Obj c -> Int
doFoo (Obj x) = foo x

Essentially, doFoo takes any Obj c, where c is any type class which implies Foo, i.e. a type class satisfying the quantified constraint

forall a. c a => Foo a


来源:https://stackoverflow.com/questions/62673111/can-i-express-a-subclassing-constraint

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!