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 类型系统,看看能做什么。
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 类型系统,看看能做什么。
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
与其为 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
不,这对于普通的 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,...)