Haskell中两个不相关类型之间的大小写

时间:2013-08-01 19:53:39

标签: haskell types type-systems

是否可以在Haskell中的两个不相关类型之间使用case表达式,如此示例(不工作)代码:

data A = A
data B = B

f x = case x of
  A -> 1
  B -> 2

main = do
  print $ test A
  return ()

我知道我可以在这里使用Either,但这段代码并不打算使用 - 我想深入学习Haskell类型系统并看看可以做些什么。

3 个答案:

答案 0 :(得分:6)

AB是不同的类型。如果你想要一个可以获取多种类型值的函数,你需要一个类型类。

data A = A
data B = B

class F a where
  f :: a -> Int

instance F A where
  f _ = 1

instance F B where
  f _ = 2

main = do
  print $ f A

答案 1 :(得分:1)

不,使用普通的case语句是不可能的,但你可以使用类型类来破解这类事情:

data A = A
data B = B

class Test a where
    test :: a -> Int

instance Test A where test = const 1
instance Test B where test = const 2

main = print $ test A

但是你应该只使用它,如果真的需要,因为它很快会变得混乱,你最终需要对类型系统进行大量扩展(UndecidableInstances,OverlappingInstances,...)

答案 2 :(得分:1)

您可以使用Typeable,而不是为f编写自己的类型类 有一些ghc支持的类。你不需要在这里使用Dynamic,但是在 有些情况需要它。

{-# LANGUAGE DeriveDataTypeable #-}
import Data.Dynamic

data A = A deriving (Typeable)
data B = B deriving (Typeable)

f x | Just A <- fromDynamic x = 1
    | Just B <- fromDynamic x = 2

f2 x | Just A <- cast x = 1
     | Just B <- cast x = 2

main = do
  print $ f (toDyn A)
  print $ f2 A