是否可以在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类型系统并看看可以做些什么。
答案 0 :(得分: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
答案 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