haskell——可以从实例函数声明中访问类型变量吗?

发布于 2024-12-03 22:52:31 字数 406 浏览 4 评论 0原文

我想访问实例中的类型变量,这些变量不会显示在实例的参数中。例如,

class A a where foo :: a b
data C a
instance A C where
    foo :: forall b. C b
    foo = undefined :: C b

当然,上面的内容将在没有作用域类型表达式的情况下解析,但我有一个我真正想要的非玩具示例。

编辑

在将其粘贴为答案之前,请先 尝试您的代码!上述(丹尼尔的回答)导致

Test.hs:51:5: Misplaced type signature: foo :: forall b. C b
Failed, modules loaded: none.

I want to access type variables in an instance, that don't show up in the instance's parameters. For example,

class A a where foo :: a b
data C a
instance A C where
    foo :: forall b. C b
    foo = undefined :: C b

Of course, the above will resolve without the scoped type expression, but I have a non-toy example where I actually want it.

edit

please try your code before pasting it as an answer! The above (Daniel's answer) results in

Test.hs:51:5: Misplaced type signature: foo :: forall b. C b
Failed, modules loaded: none.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

゛清羽墨安 2024-12-10 22:52:31

我认为要克服丹尼尔的解决方案不允许为类型类函数提供签名的问题,您可以简单地定义一个顶级函数并在类型类的实例中“重命名”它。在您的简单示例中,以下内容应该有效。

{-# LANGUAGE ScopedTypeVariables #-}

class A a where 
    foo :: a b

instance A C where
    foo = foo'

foo' :: C b
foo' = undefined :: C b

I think to overcome the problem with Daniel's solution that you are not allowed to provide a signature for a type class function you can simply define a top-level function and "rename" it in the instance of the type class. In your simple example the following should work.

{-# LANGUAGE ScopedTypeVariables #-}

class A a where 
    foo :: a b

instance A C where
    foo = foo'

foo' :: C b
foo' = undefined :: C b
葬心 2024-12-10 22:52:31

虽然真正的解决方案更好,但可以使用 asTypeOf 并添加虚拟参数来解决该问题。这是一个例子,

class A a where foo2 :: b -> a b -- added parameter b
data C a
instance A C where
    foo2 x = undefined `asTypeOf` (wrapA x)

wrapA :: A C => a -> C a
wrapA = undefined

foo :: A a => a b
foo = foo2 undefined

它恰好适用于我的现实世界的例子。干杯!

While a real solution would be preferable, one can work around the problem using asTypeOf, and adding dummy parameters. Here's an example,

class A a where foo2 :: b -> a b -- added parameter b
data C a
instance A C where
    foo2 x = undefined `asTypeOf` (wrapA x)

wrapA :: A C => a -> C a
wrapA = undefined

foo :: A a => a b
foo = foo2 undefined

That happened to work for my real-world example. cheers!

橘虞初梦 2024-12-10 22:52:31

我认为在类声明中,

class A a where
    foo :: a b

foo 的类型确实是这样的

forall b. a b

,即 foo 应该与类型 b 无关。或者,b 实际上并不是类 A 的一部分。所以...我认为您不需要能够参考它?虽然我可能不明白......也许你可以在必要的地方发布一个例子?

如果您需要在多个方法中保持相同的类型,您可以使用多参数类型类:

class A a b where
    foo :: a b
    bar :: a b

I think in the class declaration

class A a where
    foo :: a b

the type of foo is really

forall b. a b

ie foo should be sort of independent of the type b. Or, b is not actually part of the class A. So... I don't think you should need to be able to refer to it? Though I might not be understanding... maybe you could post an example where it is necessary?

If you need to keep the same type across more than one method you could use a multi-parameter type class:

class A a b where
    foo :: a b
    bar :: a b
静若繁花 2024-12-10 22:52:31
{-# LANGUAGE ScopedTypeVariables #-}
class A a where foo :: a b
instance A C where
    foo :: forall b. C b
    foo = undefined :: C b

了解更多。

{-# LANGUAGE ScopedTypeVariables #-}
class A a where foo :: a b
instance A C where
    foo :: forall b. C b
    foo = undefined :: C b

Read more.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文