这是说明问题的代码:
{-# LANGUAGE QuantifiedConstraints #-}
class SomeClass a b where
someFunction :: a -> b -> a
data FirstInInstanceOfSomeClass = forall a. (forall b. SomeClass a b) => First a
instance SomeClass Bool String where
someFunction = const
x = First True {-
• No instance for ‘SomeClass Bool b’
arising from the head of a quantified constraint
arising from a use of ‘First’
• In the expression: First True
In an equation for ‘x’: x = First Truetypecheck(-Wdeferred-
type-errors)
-}
我希望
x
是一个有效值,因为 SomeClass
存在一个 Bool
的实例,即带有 String
的实例。有办法实现吗?
澄清:我认为可能有很多
SomeClass
的实例,其中 Bool
位于第一个位置。我想要要求的是 Bool
至少应该有一个这样的实例,以便 FirstInInstanceOfSomeClass
可以包裹 Bool
值。
你的
FirstInInstanceOfSomeClass
没有意义:你希望 a
是一个参数,而不是存在性的,然后 b
应该是存在性的(如 (exists b. SomeClass a b) => First a
中,或者等效地通过柯里化得到 forall b. SomeClass a b => First a
,这是Haskell 支持的语法)。
data FirstInInstanceOfSomeClass a = forall b. SomeClass a b => First a
当然,编译器现在抱怨
b
在First
的类型上不明确;如果您对 b
存在 a
的功能依赖性,解决此问题的一种方法是声明它:
{-# LANGUAGE FunctionalDependencies #-}
class SomeClass a b | a -> b where
someFunction :: a -> b -> a
否则,您可以使用旧的
Proxy
技巧,或者使用 GADT 语法并使用类型应用程序。