Generics Haskell中基于某些谓词的泛型函数结果

Generics Haskell中基于某些谓词的泛型函数结果,generics,haskell,types,typeclass,type-systems,Generics,Haskell,Types,Typeclass,Type Systems,是否可以在haskell中编写函数,该函数在以下情况下返回泛型类型: 在这个函数的主体中,我们输出了两种不同的类型a和B(基于一些计算) 类型A和B有一个共同的类型类C 让我们看看示例代码。类型检查器应该能够检查此代码是否正确-函数test输出类型A或B的实例,因此我们可以对结果执行f data A = A data B = B class C a where f :: a -> Int instance C A where f x = 2 instance C

是否可以在haskell中编写函数,该函数在以下情况下返回泛型类型:

  • 在这个函数的主体中,我们输出了两种不同的类型
    a
    B
    (基于一些计算)
  • 类型
    A
    B
    有一个共同的
    类型类
    C
让我们看看示例代码。类型检查器应该能够检查此代码是否正确-函数
test
输出类型
A
B
的实例,因此我们可以对结果执行
f

data A = A 
data B = B

class C a where
    f :: a -> Int

instance C A where
    f x = 2

instance C B where
    f x = 3

-- This function fails to compile:
-- I want something like:
-- test :: C a => Int -> a
test x = if x < 1  
        then A
        else B

main = do
    print $ f $ test 0
    print $ f $ test 1
数据A=A
数据B=B
丙级甲级在哪里
f::a->Int
实例C A其中
fx=2
实例C B在哪里
fx=3
--此函数无法编译:
--我想要像这样的东西:
--测试::CA=>Int->a
测试x=如果x<1
然后
其他B
main=do
打印$f$测试0
打印$f$测试1

我知道这可能看起来像反模式或类似的东西,但我想知道答案,因为我喜欢测试Haskell特性,尤其是在类型系统方面。

这里的问题是,Haskell的类型变量是普遍量化的

这意味着它们可以理解为

forall a. C a => Int -> a
这意味着调用者选择
a
的具体类型。不是被叫人

要解决这个问题,您需要一种叫做“存在”变量的东西。普遍量化变量应理解为“全部”,存在量化变量应理解为“存在”

如何完成此操作的快速草图

{-# LANGUAGE ExistentialQuantification, GADTs #-}

-- Use existentials 
data Box = forall a. C a => Box a

-- Use GADTs
data Box' where
  Box' :: C a => a -> Box'

instance C Box where
    f (Box a) = f a

test :: Int -> Box
test x = if x < 1  
    then Box A
    else Box B
有趣的存在变量怪癖,用GHC试试这段代码

fun = foo
  where (Box foo) = test 1

text::ca=>Int->a
意味着调用方可以选择类型
a
——通用量化。如果被调用方可以选择,您需要一个存在的:
datasomec,其中SomeC::ca=>a->SomeC
。问题是,这可以通过使用非指示类型来实现吗?您的意思是说“普遍量化”而不是“普遍限定”吗?
fun = foo
  where (Box foo) = test 1