无论如何,即使使用奇怪的GHC扩展组合,也可以像下面的psudeocode一样创建一个函数h
:
f :: (C1 a) => a -> Int
g :: (C2 a) => a -> Int
h x =
if (isOfClass C1 x) then (f x)
else if (isOfClass C2 x) then (g x)
else COMPILE_ERROR
请注意,如果x
同时属于C1
和C2
,我不会介意,如果我的行为不一致,具体取决于范围内的内容。
答案 0 :(得分:3)
将值换行为其他类型,例如Either
或自定义类型
Either
的示例:
h :: (C1 a, C2 b) => Either a b -> Int
h = either f g
答案 1 :(得分:3)
这是不可能的,因为它可以应对单独的编译。考虑
module A where
data A = A Int
isOfClassEq :: a -> Bool
isOfClassEq = <<some magic here>>
test :: Bool
test = isOfClassEq (A 42)
和
module Main where
import A
instance Eq A where (A x) == (A y) = x == y
main = print test
如果我在GHCi中打开了模块A
,则test
将评估为False
。因此,与test
关联的代码必须返回False
。相反,如果我加载模块Main
并运行main
,我应该看到True
。如果我们有单独的编译,由于编译器在编译模块A
时无法知道实例,因此必须生成test
的代码,该代码在运行时检查类成员资格。
这将要求GHC保持运行时所有类型信息,包括类型&lt; - &gt;类表以执行检查。但是,Haskell的设计使得在编译期间可以丢弃类型信息。