【发布时间】:2020-06-18 21:19:25
【问题描述】:
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE ExplicitForAll #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ExistentialQuantification #-}
import Data.Proxy
data Foo = FooA | FooB
class Bar (a :: k) where
bar :: Proxy a -> Int
instance Bar FooA where
bar _ = 1
instance Bar FooB where
bar _ = 2
foo1 :: forall (a :: Foo). Proxy a -> (Bar a => Proxy a)
foo1 p = p
data BarProxy = BarProxy (forall a. Bar a => Proxy a)
foo2 :: forall (a :: Foo). Proxy a -> BarProxy
foo2 p = BarProxy (foo1 p)
main = print "Hello World"
在这段代码中:
- 没有
foo1,给定任何Proxy a,其中a是一种Foo,返回一个Proxy a使得a有一个Bar的实例? -
BarProxy构造函数不接受任何Proxy a,其中a有Bar的实例?与data BarProxy = forall a. BarProxy (Bar a => Proxy a)有何不同? - 为什么
foo2 p = BarProxy (foo1 p)失败并出现以下错误?
Test6.hs:27:20: error:
• Couldn't match type ‘a1’ with ‘a’
‘a1’ is a rigid type variable bound by
a type expected by the context:
forall (a1 :: Foo). Bar a1 => Proxy a1
at Test6.hs:27:10-26
‘a’ is a rigid type variable bound by
the type signature for:
foo2 :: forall (a :: Foo). Proxy a -> BarProxy
at Test6.hs:26:1-46
Expected type: Proxy a1
Actual type: Proxy a
• In the first argument of ‘BarProxy’, namely ‘(foo1 p)’
In the expression: BarProxy (foo1 p)
In an equation for ‘foo2’: foo2 p = BarProxy (foo1 p)
• Relevant bindings include
p :: Proxy a (bound at Test6.hs:27:6)
foo2 :: Proxy a -> BarProxy (bound at Test6.hs:27:1)
|
27 | foo2 p = BarProxy (foo1 p)
| ^^^^^^
【问题讨论】:
-
不确定其他问题,但您对 (2) 是正确的;对于 (3),它失败了,因为它接受
Proxy a,其中a是Foo的实例,但BarProxy构造函数需要a这是Bar的实例(我认为) .另外,我必须说我以前从未见过(Bar a => Proxy a)的语法,其中a不是用forall量化的;你在哪里看到的? -
@bradrn,我在其他地方没见过。我最近才知道,
BarProxy (forall a. Bar a => Proxy a)内部是BarProxy (<Bar instance for a>, Proxy a),而foobar :: Bar a => Proxy a -> Int是foobar :: <Bar instance> -> Proxy a -> Int。我想了解实例是如何在返回位置传递的。 -
你也可以用类似游戏的语义here来描述我对
forall的描述。
标签: haskell