3

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

data A = A
data B = B

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

main = do
  print $ test A
  return ()

我知道我可以Either在这里使用,但是这段代码并不是要使用的——我想深入学习 Haskell 类型系统,看看能做什么。

4

3 回答 3

6

A并且B是不同的类型。如果你想要一个可以接受多种类型值的函数,你需要一个类型类。

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
于 2013-08-01T19:59:09.617 回答
1

与其为 f 编写自己的类型类,不如使用 ghc 支持的 Typeable 类。您不需要在此处使用 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
于 2013-08-01T20:37:28.763 回答
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,...)

于 2013-08-01T20:00:30.330 回答