如果某事物只能有两种类型,那么它就不是“多态的”。这只是两种类型的不相交并集,或“和”类型。
import Data.Int
data Idx = I32 Int32
| I64 Int64
deriving (Show)
readId 4 _ = I32 0x12345678
readId _ _ = I64 0x1234567812345678
idSize (I32 _) = 4
idSize _ = 8
main :: IO ()
main = do
let input = () -- this would be your input stream
let idx1 = readId 4 input
let idx2 = readId 8 input
putStrLn $ "idx 1: size " ++ (show $ idSize idx1) ++ " value: " ++ (show idx1)
putStrLn $ "idx 2: size " ++ (show $ idSize idx2) ++ " value: " ++ (show idx2)
return ()
当您确实需要数据类型的类型签名具有更大的灵活性时,例如当您正在构建一个抽象语法树并希望将其限制为类型良好的结构时,GADT 是一种不错的方法:http://en.wikibooks .org/wiki/Haskell/GADT
这是 GADT 的示例:
{-# LANGUAGE GADTs #-}
{-# LANGUAGE StandaloneDeriving #-}
import Data.Int
data Idx a where
I32 :: Int32 -> Idx Int32
I64 :: Int64 -> Idx Int64
deriving instance Show (Idx a)
readId32 :: t -> Idx Int32
readId32 _ = I32 0x12345678
readId64 :: t -> Idx Int64
readId64 _ = I64 0x1234567812345678
idSize :: Num a => Idx t -> a
idSize (I32 _) = 4
idSize _ = 8
main :: IO ()
main = do
let idx1 = readId32 ()
let idx2 = readId64 ()
putStrLn $ "idx 1: size " ++ (show $ idSize idx1) ++ " value: " ++ (show idx1)
putStrLn $ "idx 2: size " ++ (show $ idSize idx2) ++ " value: " ++ (show idx2)
return ()
我不确定这是否正是您所追求的,但它确实让您可以专门化类型,这样您就不能将Idx Int32
s 与Idx Int64
s 混合,但您仍然可以编写多态Idx a
函数,例如idSize
.