Chr*_*non 3 haskell types algebraic-data-types data-structures
当类型X定义为:
data X =
X { sVal :: String } |
I { iVal :: Int } |
B { bVal :: Bool }
Run Code Online (Sandbox Code Playgroud)
我希望Int里面有一个X值,如果有的话,否则为零.
returnInt :: X -> Int
Run Code Online (Sandbox Code Playgroud)
如何确定X参数的类型returnInt?
Cat*_*lus 13
使用模式匹配.
returnInt :: X -> Int
returnInt (I x) = x
returnInt _ = 0
Run Code Online (Sandbox Code Playgroud)
Gre*_*con 10
对所有可能的X值使用更灵活的定义:
returnInt :: X -> Maybe Int
returnInt (I i) = Just i
returnInt _ = Nothing
Run Code Online (Sandbox Code Playgroud)
然后你可以使用maybe你想要的特定默认值-0可能是一个有效值(这被称为半无差别问题):
*Main> maybe 0 id (returnInt $ X "")
0
*Main> maybe 0 id (returnInt $ I 123)
123
*Main> maybe (-1) id (returnInt $ X "yo")
-1
Run Code Online (Sandbox Code Playgroud)
相反,部分函数存在运行时异常风险:
*Main> let returnInt (I i) = i
*Main> :t returnInt
returnInt :: X -> Int
*Main> returnInt (B True)
*** Exception: <interactive>:1:4-22: Non-exhaustive patterns in function returnInt
Run Code Online (Sandbox Code Playgroud)
如果你感觉真的很蛙,你可以使用 MonadPlus
returnInt :: (MonadPlus m) => X -> m Int
returnInt (I i) = return i
returnInt _ = mzero
Run Code Online (Sandbox Code Playgroud)
获得更大的灵活性:
*Main> maybe 0 id (returnInt $ X "")
0
*Main> maybe 0 id (returnInt $ I 123)
123
*Main> returnInt (I 123) `mplus` returnInt (I 456) :: [Int]
[123,456]
Run Code Online (Sandbox Code Playgroud)