【问题标题】:Can I express a subclassing constraint?我可以表达一个子类约束吗?
【发布时间】:2020-07-01 18:58:59
【问题描述】:

仍然在玩存在主义而不是约束(只是探索这个设计空间,我知道许多 Haskeller 认为它很糟糕)。请参阅this question 了解更多信息。

{-# 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 FooObj Bar 不同。

我可以给doFoo一个合适的类型吗?基本上我想要一个像Obj cls where cls is a subclass of Foo 这样的类型,但我找不到表达它的方法。请多多包涵,我对这些狂野的类型很陌生。

【问题讨论】:

    标签: haskell types typeclass existential-type


    【解决方案1】:

    您可以为此使用量化约束:

    {-# LANGUAGE QuantifiedConstraints #-}
    
    doFoo :: forall c . (forall a. c a => Foo a) => Obj c -> Int
    doFoo (Obj x) = foo x
    

    本质上,doFoo 接受任何Obj c,其中c 是暗示Foo 的任何类型类,即满足量化约束的类型类

    forall a. c a => Foo a
    

    【讨论】:

    • 谢谢,我一直在寻找 QuantifiedConstraints!
    猜你喜欢
    • 2019-10-14
    • 2011-04-22
    • 2011-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-25
    • 1970-01-01
    相关资源
    最近更新 更多